取余的妙用
链接:https://ac.nowcoder.com/acm/contest/68346/C
来源:牛客网
游游制定了一个刷题计划,她找到了\(n\)套试卷,每套试卷的题目数量为\(a_i\)。游游每天上午最多打开一套试卷,下午最多打开一套试卷,也可以选择不刷题而摸鱼。当游游打开一套试卷后,她就会把上面的题目全部刷完。但是游游有强迫症,她希望每天刷的题目总数均为\(k\)的倍数。请你计算游游最多能刷多少天的题?
输入描述:
第一行输入两个正整数\(n\)和\(k\)。
第二行输入\(n\)个正整数\(a_i\)
\(1\leq n \leq 10^5\)
\(1\leq k,a_i \leq 10^9\)
输出描述:
一个整数,代表游游最多能刷题的天数。
示例1
输入
5 3
1 2 3 4 5
输出
3
说明
第一天上午刷1号试卷,下午刷5号试卷,总共刷6题。
第二天上午摸鱼,下午刷3号试卷,总共刷3题。
第三天上午刷4号试卷,下午刷2号试卷,总共刷6题。
示例2
输入
5 3
1 1 1 1 1
输出
0
说明
显然,游游没有任何一个方案可以开始刷题。
这个题是取余的妙用,注意题目中说最多能刷多少天
对于第i天的题量\(a[i]\),如果a[i]%k==0,那个就让他这一天就做这一个,上午做下午摸鱼。
如果第i天的题量不是k的倍数,那么我们可以用一个数组将\(a[i]%k\)储存起来,然后我们下一次遍历到\(k-a[i]%k\)的时候那么这两个就可以配对了。这是因为取余的时候(a%k-b%k+k)=(a-b+k)%k
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e5+100;
int a[maxn];
map<int,int>p;
int main(){
int n,k;
cin>>n>>k;
int ans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]%k==0){
ans++;
}
else{
if(p[k-a[i]%k]>0){
ans++;
p[k-a[i]%k]--;
}
else{
p[a[i]%k]++;
}
}
}
cout<<ans<<endl;
return 0;
}