2020杭电多校第三场 1004 Tokitsukaze and Multiple

题目

2020杭电多校第三场 1004 Tokitsukaze and Multiple_第1张图片
题目链接

题目大意是给定n个数字的序列,可以任意合并其中相邻的数字,使他们相加,问最多能有多少个p的倍数。

贪心

这个题可以使用贪心的写法来解决。首先p的倍数这种事情重点只有余数部分,所以先对所有数字取模,且每次相加都要取模。只需要关心最终能搞出几个零就行了。

可以直接遍历整个数组,加上新来的数字,如果加上后这个余数在前面出现过则证明以该数字位结尾的一段数字加和是p的倍数,统计入答案,并重置标记数组。重复这个过程即可。

另外,对于重置标记数组,如果每次都循环置零,那么就会超时,可以使用一个小技巧,使用一个cnt变量来进行标记,这样每次需要重置标记数组时,就不需要置零,只需要改变cnt到一个未出现过的值即可,通常让其++;

代码:

#include
#include
#define N 100050
using namespace std;
int a[N];
int vis[N];
int p,n,T,cnt = 0,ans;
int main(){
	for(cin >> T;T;T--){
		scanf("%d%d",&n,&p);
		ans = 0;
		for(int i = 1;i <= n;i++){
			scanf("%d",&a[i]);
			a[i] %= p;
		}
		cnt++;
		int sum = 0;
		for(int i = 1;i <= n;i++){
			sum += a[i];
			sum %= p;
			if(vis[sum] == cnt || sum == 0){
				ans++;
				sum = 0;
				cnt++;
				continue;
			}
			vis[sum] = cnt;
		}
		printf("%d\n",ans);
		
	}
}

你可能感兴趣的:(题解,算法,数据结构)