CF1883C
2023-11-01 22:26:40 # OI # Problem

题面

Link

题意:给你一个序列,每次可以选择一个数并把它加一,求让这个序列能被 kk 整除的最小操作次数。

思路

我们观察到 2k52\le k \le 5 那么 kk 的取值除了 44 就一定是质数,也就是说序列中一定要有一个数为 kk,所以我们找到最接近 kk 的倍数的一个数,操作它即可。

那么怎么找最接近 kk 的倍数的数呢?模 kk 的值最大即可。

假如原来就有 kk 了,那就不用操作了。

至于 k=4k=4 的情况,特判一下两个 22 的即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 8;

int a[N];

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, k;
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
        }
        // k <= 5
        sort(a + 1, a + 1 + n);
        int maxn = -1;
        if(k == 4)
        {
            int cnt = 0;
            bool bj = false;
            for(int i = 1; i <= n; i++)
            {
                if(a[i] % 4 == 0)
                {
                    bj = true;
                    cout << 0 << endl;
                    break;
                }
                if(a[i] % 2 == 0) cnt++;
                maxn = max(maxn, a[i] % 4);
            }
            if(bj) continue;
            if(cnt >= 2)
            {
                cout << 0 << endl;
            }
            else if(cnt == 1) cout << 1 << endl;
            else cout << min(4 - maxn, 2) << endl;
            continue;
        }
        bool bj = false;
        for(int i = 1; i <= n; i++)
        {
            if(a[i] % k == 0)
            {
                bj = true;
                cout << 0 << endl;
                break;
            }
            maxn = max(maxn, a[i] % k);
        }
        if(bj) continue;
        cout << k - maxn << endl;
    }
    return 0;
}