b_51_N的倍數(抽屜原理+字首和)
阿新 • • 發佈:2020-10-25
一個長度為N的陣列A,從A中選出若干個數,使得這些數的和是N的倍數。
2<=N<=50000;0<A[i]<=10^9
思路:A[i]對N取模的結果為1~N-1(共N-1個數),而A有N個數,這就說明這些模N的數中至少有兩個數是一樣的(抽屜原理保證了資料一定有解);然後就是分兩種情況:
- 字首和s[0:i]中有0出現,則輸出A[0~i]
- 否則,如果存在兩個字首s[i]和s[j](i!=j)和它們的值相等,則證明s[j...i]這一段一定是n的倍數(模n為0)
這裡咬注意啊:下標從0開始的話如果第一個數就是n的倍數,需要特判一下,因為這句:cout<<i-j<<'\n';
#include<bits/stdc++.h> #define rep1(i,s,e) for( int i=s;i<=e;i++) #define rep2(i,s,e) for( int i=e;i>=s;i--) using namespace std; typedef long long ll; const int N=5e5+5; ll n,s,a[N],mp[N]; int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; rep1(i,1,n) cin>>a[i]; //mp[0]=0; rep1(i,1,n) { s=(s+a[i])%n; if (s==0 || mp[s]) { int j=mp[s]; cout<<i-j<<'\n'; rep1(k,j+1,i) cout<<a[k]<<'\n'; break; } else { mp[s]=i; } } return 0; }