POJ 3370 鴿巢原理
阿新 • • 發佈:2018-12-11
這個題要知道一個定理。
給定m個數,a1,a2,a3,.....am,至少存在整數k,l,(1<=k<l<=m)使得ak+....+al是m的倍數。
構造字首和:
s1=a1;
s2=a1+a2;
s3=a1+a2+a3;
...
sm=a1+a2+...+am;
(1)如果有一個sn是m的倍數,則定理得證。
(2) 如果在上面沒有一個是m的倍數。令rh=Sh%m
其中,h=1,2,.....m,則所有rh均小於m,根據鴿巢定理可知至少存在一對rk,rh,滿足rk==rh
即 Sk ≡ Sh % m
不過我寫的G++TLE,C++AC
#include<cstdio> #include<algorithm> using namespace std; const int maxn=1e5+10; struct node{ int r,h; }p[maxn]; bool cmp(const node& a,const node& b){ if(a.r==b.r) return a.h<b.h; return a.r<b.r; } int main(){ int c,n; while(scanf("%d%d",&c,&n)!=EOF&&(c||n)){ long long sum=0; int a; int k=-1; for(int i=1;i<=n;i++){ scanf("%d",&a); sum+=a; p[i].r=sum%c; p[i].h=i; if(k==-1&&p[i].r==0) k=i; } int l,r; if(k==-1){ sort(p+1,p+1+n,cmp); for(int i=1;i<n;i++){ if(p[i].r==p[i+1].r){ l=p[i].h+1; r=p[i+1].h; k=l; break; } } }else{ l=1;r=k; } if(k==-1){ printf("no sweets\n"); }else{ for(int i=l;i<=r;i++){ if(i!=l) printf(" "); printf("%d",i); } puts(""); } } return 0; }