poj Find a multiple【鸽巢原理】

参考:https://www.cnblogs.com/ACShiryu/archive/2011/08/09/poj2356.html
鸽巢原理???
其实不用map但是习惯了就打的map
以下C-c自参考博客:
我们可以依次求出a[0],a[0]+a[1],a[0]+a[1]+a[2],......,a[0]+a[1]+a[2]...+a[n];
假设分别是sum[0],sum[1],sum[2],......,sum[n]
如果在某一项存在是N的倍数,则很好解,即可直接从第一项开始直接输出答案
但如果不存在,则sum[i]%N的值必定在[1,N-1]之间,又由于有n项sum,有抽屉原理:
把多于n个的物体放到n个抽屉里,则至少有一个抽屉里有2个或2个以上的物体。
则必定有一对i,j,使得sum[i]=sum[j]

所以用map记一下余数的出现位置,然后直接在map里找即可

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
const int N=10005;
int n,a[N],s[N];
map<int,int>mp;
int main()
{
	while(~scanf("%d",&n))
	{
		mp.clear();
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
		for(int i=1;i<=n;i++)
			if(s[i]%n==0)
			{
				printf("%d\n",i);
				for(int j=1;j<=i;j++)
					printf("%d\n",a[j]);
				return 0;
			}
		for(int i=1;i<=n;i++)
		{
			if(mp[s[i]%n])
			{
				printf("%d\n",i-mp[s[i]%n]);
				for(int j=mp[s[i]%n]+1;j<=i;j++)
					printf("%d\n",a[j]);
				return 0;
			}
			mp[s[i]%n]=i;
		}
	}
	return 0;
}
posted @ 2018-07-01 16:14  lokiii  阅读(127)  评论(0编辑  收藏  举报