poj 2356 Find a multiple【抽屜原理】
阿新 • • 發佈:2018-12-07
題目連結:http://poj.org/problem?id=2356
題目大意:題目大意就是先給出一個數N,接著再給出N個數,要你從這N個數中任意選擇1個或多個數,使得其和是N的倍數如果找不到這樣的答案 則輸出0,答案可能有多個,但只用任意輸出一個解就行。
思路:可以先計算出S1,S2,S3……Sn(表示從第一個到第n個數字的和);如果其中Si%N==0的,直接輸出;
抽屜原理:把多於n個的物體放到n個抽屜裡,則至少有一個抽屜裡有2個或2個以上的物體。
否則,就讓每個S1~n對n取模,如果最終答案不是0,那麼肯定有Si%N==Sj%N,那麼假設j>n,則(Sj-Si)%N==0,所以輸出從i+1到 j 的數就OK了;
#include<stdio.h> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<set> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N=1e6+10; int sum[N]; int num[N]; int vis[N]; int main() { int n; while(~scanf("%d",&n)) { int flag=0; memset(vis,0,sizeof(vis)); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=1;i<=n;i++) { sum[i]=sum[i-1]+num[i]; if(sum[i]%n==0)//如果當前sum[i]%n==0,直接輸出 { flag=1; printf("%d\n",i); for(int j=1;j<=i;j++) printf("%d\n",num[j]); break;//記得加上break,第一次就是這裡沒加WA了 } } if(!flag) { int t; for(int i=1;i<=n;i++) { t=sum[i]%n; if(vis[t]!=0) { printf("%d\n",i-vis[t]); for(int j=vis[t]+1;j<=i;j++) printf("%d\n",num[j]); break; } vis[t]=i; } } } return 0; }