1. 程式人生 > >N的倍數-抽屜原理-字首和

N的倍數-抽屜原理-字首和

題目傳送門
題意:
給你N個數,要你從這N個數中選出幾個數,他們的和恰好是N的整數倍。輸出所選數的個數,和數。
思路:
這道題要用到容斥原理。首先,N個數有N個字首和,他們%N的餘數,要麼全部不相同,即0->N-1,這種情況,餘數為0的字首和就是所求的區間。
另外一種情況就是,至少有2個字首和%N的餘數是相同的,那麼他們之間的差值就是N的倍數。他們之間的區間就是所求區間。
教訓:
思考問題時,不能被樣例的答案所侷限,這是設題者的坑。還有不要總是用模擬的思路去思考問題,要將問題轉化與化歸,從變中尋找不變。

AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
map<int,int> mp;
const int maxn = 5e4 + 10;
int sum[maxn];
int a[maxn];
int n = 0;

int main(){
	while(~scanf("%d",&n)){
		fill(sum,sum+maxn,0);
		mp[0] = 0;
		for(int i = 1;i <= n;++i){
			scanf("%d",&a[i]);
			sum[i] = (sum[i-1] + a[i]) % n;
			if(mp.count(sum[i]) == 1){
				printf("%d\n",i - mp[sum[i]]);
				for(int j = mp[sum[i]] + 1;j <= i;++j){
					printf("%d\n",a[j]);
				}
				return 0;
			}
			mp[sum[i]] = i;
		}
		
	}
	
	return 0;
}