取余的妙用

链接: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; 
}
posted @ 2023-11-11 11:09  lipu123  阅读(33)  评论(0)    收藏  举报