atcoder ARC 086 CD题解

本文介绍两道算法题目解决方案。一是调整数组中元素值确保不超过k种不同数值的最小变动数;二是通过一系列操作使数组变为非递减序列,详细步骤包括寻找最大值并利用前缀或后缀策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门
C: 问最少要给多少个元素重新赋值, 使得这个数组中最多只有k种数字.

直接记录每个数字出现的次数, 然后从大到小排个序, 从第k+1种那开始选去后面的元素即可.

AC Code

int a[maxn];
bool cmp(int a, int b) {
    return a > b;
}
void solve()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1 ; i <= n ; i ++) {
        int x; cin >> x ;
        a[x]++;
    }
    sort(a+1, a+1+n, cmp);
    int ans = 0;
    for (int i = k + 1 ; a[i] ; i ++) ans+=a[i];
    cout << ans << endl;
}

D: (好题!)
给定一个数组, 每次操作可以选择一对位置(x, y) , 然后可以ay += ax, 输出这些具体操作使得这个数组变成一个非递减的数组. 操作数在[0, 2*n]范围内都是对的.

我们首先简化下这个问题, 如果这个数组中的元素全是正的或者全是负的, 怎么来整,很明显用前缀或者后缀的思想就可以轻松变成一个非递减数组, 所以我们就找这个数组中的最大值, 然后让每个数都加上这个数这样问题就变成了我们简化过的那个问题了, 通过最大值的正负来确定是前还是后缀即可.

AC Code

const int maxn = 50+5;
int cas=1;
int a[maxn];
void solve()
{
    int flag, mx = -1, pos;
    int n; scanf("%d", &n);
    for (int i = 1 ; i <= n ; i ++) {
        scanf("%d", a+i);
        if (abs(a[i]) > mx) {
            mx = abs(a[i]);
            flag = a[i] < 0 ? -1 : 1;
            pos = i;
        }
    }
    printf("%d\n", 2*n - 2);
    for (int i = 1 ; i <= n ; i ++) {
        if (i == pos) continue;
        printf("%d %d\n",pos, i);
    }
    if (flag == 1) {
        for (int i = 1 ; i < n ; i ++) {
            printf("%d %d\n", i, i+1);
        }
    }
    else {
        for (int i = n - 1 ; i >= 1 ; i --) {
            printf("%d %d\n", i+1, i);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值