Codeforces Round #653 (Div. 3) D. Zero Remainder Array

  • 题意
    给定一个长度为n的数组nums
    初始化一个x = 0, 每次你可以有两种操作:
    1)x ++
    2)nums 任意一个元素 + x。其中每个元素最多加一次x。
    最终目的是让数组中每个元素都能被给定的一个k整除。
  • 思路 :
    对于一个数 tmp,我们考虑两种情况:
    1) tmp < k
    若是tmp + x mod k = 0, 则可以得到 tmp = A*k - x.
    可知如果要得到结果,x from 1 to k 这样的更新迭代期间,便可让tmp得到最终结果。
    如果其中有两个相同数值的tmp,则在 x from 1 to k 期间,使其中一个数字满足条件,然后在 x from k to 2k期间,使得另外一个数得到满足。
    可以发现需要的迭代次数res 与 相同数值tmp的个数 num之间的关系是res = num。而使得num个数都能满足要求,x最终的值为:
    x = (res-1)*k + (k - tmp)。因为第一次x 更新到 k - tmp时,满足一个tmp,然后再迭代 k个数,可以满足另一个tmp。
    2)tmp > k
    当tmp > k时,其与k之间的距离便是 k - tmp%k。
    所以可以得到,x = (res-1) * k + (k - tmp%k).
    其中的res 是 tmp%k相同的数。
  • 代码:
#include "bits/stdc++.h"
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef long long ll;
const int maxn = 1e4 + 7;
const int INF =INT_MAX;
const double EPS = 10;
// #define _DEBUG

int main(){
    
    
#ifdef _DEBUG
    freopen("./Files/in.txt", "r", stdin);
    freopen("./Files/out.txt", "w", stdout);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);

    int T;
	cin >> T;
    map<int, int> cnt;
	while(T --){
    
    
		int n, k;
		cin >> n >> k;
		cnt.clear();
		for(int i = 0;i < n;i++){
    
    
			int x;
			cin >> x;
			if(x % k == 0) continue;
            cnt[k - x%k] ++;
		}
		ll ans = 0;
		for(auto i :cnt){
    
    
			if(i.first == 0) continue;
			ans = max(ans, (ll)(i.second - 1) * k + i.first);
			// cout << i.first << " " << i.second << endl;
		}
        // cout<<"The ans is : ";
		if(ans)cout << ans + 1<< endl;
		else cout << ans << endl;
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39763472/article/details/107017434