POJ2356 Find a multiple
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2356 Find a multiple相关的知识,希望对你有一定的参考价值。
题解:
所谓鸽巢原理,通俗理解就是把n+1个物品放进n个盒子中,那么一定有一个盒子有2个物品
这题可以得到结论。
n个数中,必定有连续的m个数和sum,使得sum%n==0.
证明:
对于:sum[k]=a[1]+a[2]+.........a[k],1<=k<=n,若sum[k]%n==0。则直接得到,否则1<=sum[k]%n<=n-1。sum数组的大小为n,
那么,一定存在i,j使得sum(j)%n==sum(i)%n。故(sum(i)-sum(j))%n==0。即证
参考博客http://blog.csdn.net/acm_cxlove/article/details/7432166
代码:
vector保存
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<map> #include<set> #include<vector> using namespace std; using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define ls o<<1 #define rs o<<1|1 #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) typedef pair<int,int> P; const double eps=1e-9; const int maxn=20100; const int N=1e9; const int mod=1e9+7; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- ll a[maxn],sum[maxn]; vector<int> s[maxn]; int main(){ int n; n=read(); for(int i=1;i<=n;i++){ a[i]=read(); sum[i]=sum[i-1]+a[i]; s[sum[i]%n].pb(i); } if(s[0].size()>0){ printf("%d\n",s[0][0]); for(int i=1;i<=s[0][0];i++) printf("%d\n",a[i]); } else{ for(int i=1;i<=n-1;i++){ if(s[i].size()>1){ int c=s[i][0],b=s[i][1]; printf("%d\n",b-c); for(int j=c+1;j<=b;j++) printf("%d\n",a[j]); break; } } } return 0; }
直接模拟coding by cxlove
/* ID:cxlove PROB:POJ 2356 DATA:2012.4.6 HINT:鸽巢原理 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){ int n,k; int a[10005]={0},b[10005]; while(scanf("%d",&n)!=EOF){ bool flag=false; memset(b,0,sizeof(b)); for(int i=1;i<=n;i++){ scanf("%d",&k); if(flag) continue; a[i]=a[i-1]+k; if(a[i]%n==0){ printf("%d\n",i); for(int j=1;j<=i;j++) printf("%d\n",a[j]-a[j-1]); flag=true; } else if(b[a[i]%n]){ printf("%d\n",i-b[a[i]%n]); for(int j=b[a[i]%n]+1;j<=i;j++) printf("%d\n",a[j]-a[j-1]); flag=true; } else b[a[i]%n]=i; } } return 0; }
以上是关于POJ2356 Find a multiple的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2356. Find a multiple 抽屉/鸽巢原理
[POJ2356]Find a multiple 题解(鸽巢原理)