Description
给你一个有 n个正整数的序列 a 。
最开始你有一个整数 x = 0 。每次操作你有两种选择:
-
选择一个下标 i ,令 a i a_{i} ai 的值增加 x ,然后让 x 加1
-
仅让 x 加 1
对于第一种操作,每个下标 i 至多被选择一次。
你的任务是找到最小的操作次数,使 n 个元素都能被 kk 整除。
题目将会有 t 组独立的数据。
Input
第一行输入包含一个正整数 tt (1 ≤ \leq ≤ t ≤ \leq ≤ 10),表示接下来会有 t 组数据。
每一组数据首先输入两个正整数 n 和 k (1
≤
\leq
≤ n
≤
\leq
≤ 1e5 ;1
≤
\leq
≤k
≤
\leq
≤ 1e9 ),之后一行包含 n 个正整数
a
i
a_{i}
ai(1
≤
a
i
\leq a_{i}
≤ai
≤
\leq
≤ 1e9)
Output
对于每一组数据,在一行中输出一个数字表示所需要的最少的操作次数。
Sample
Input
5
4 3
1 2 1 3
10 6
8 7 1 8 3 7 5 10 8 9
5 10
20 100 50 20 100500
10 25
24 24 24 24 24 24 24 24 24 24
8 8
1 2 3 4 5 6 7 8
Output
6
18
0
227
8
Hint
解题思路:直接解就是找相同的话很困难,所以我们可以mod上k,这样都变成了一个小于k的数,因为必须是加上一个数是可以整除k的,所以我们可以找他需要加上多少,所以我们可以进行(k-x%k)%k,这样操作可以使得能够整除k的为0,而不能够整除k的算出还差多少等于k,然后进行操作即可,这里应该注意的是他的操作,操作要求的是对数x直接加1或是先加入到对应的数上然后再加1,注意的是第二种操作+1是后面的操作。
想到mod后本题也就好做多了。
下面是AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+3;
vector<ll> a;
int main()
{
ll t,n,k,x,ans;
cin>>t;
while(t--)
{
a.clear();
cin>>n>>k;
for(int i=1;i<=n;i++)
{
ll x;
cin>>x;
if((k-x%k)%k!=0) a.push_back((k-x%k)%k);
}
if(a.size()==0) printf("0\n");//这里尽量单独讨论。
else
{
sort(a.begin(),a.end());
ll len=a.size();
ll num=1,maxnum=0,maxi;
a[len]=0;
for(int i=1;i<=len;i++)//这里让等于len的原因是如果所有数都相等的话,按照这个代码的操作是无法更新的,但是如果到len,a[len]=1,这样是可以更新的
{
if(a[i-1]==a[i])
{
num++;
}
else
{
if(num>=maxnum)
{
maxnum=num;
maxi=a[i-1];
}
num=1;
}
}
ans=maxi+(maxnum-1)*k+1;//这里应该注意的是要加上1,在上面有提到
printf("%lld\n",ans);
}
}
return 0;
}