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;
}

猜你喜欢

转载自www.cnblogs.com/lokiii/p/9250427.html
今日推荐