可能是一道签到题

Description
给你一个有 n个正整数的序列 a 。

最开始你有一个整数 x = 0 。每次操作你有两种选择:

  1. 选择一个下标 i ,令 a i a_{i} ai 的值增加 x ,然后让 x 加1

  2. 仅让 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;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值