poj 3370

来源:互联网 发布:apk网络电视bbs 编辑:程序博客网 时间:2024/06/06 12:43

思路:定理:

         设a1、a2……am是正整数的序列,则至少存在整数k和l,(1<=k<l<=m),使得和a(k+1) + a(k+2) + ... ... +al是m的倍数。

  证明:x%m的余数有(m-1)中可能,即设有(m-1)个鸽巢,设sn代表(a1+a2+...+an)则m个sn产生m个余数,根据鸽巢原理,一定至少有两个s的余数相等,将这连个s想减,中间a(k+1) + a(k+2) + ... ... +al一定是m的倍数。

这题需要注意数据范围,求和的数组需定义为long long.

代码:

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;long long a[100100],b[100100],num[100100],d[100100];int main(){    int c,n;    while(scanf("%d%d",&c,&n)!=EOF)    {      if(c==0&&n==0)        break;      for(int i=0;i<=n-1;i++)      {       scanf("%d",&a[i]);      }      memset(b,0,sizeof(b));      memset(d,-1,sizeof(d));      b[0]=a[0];     for(int i=1;i<=n-1;i++)      {       b[i]=b[i-1]+a[i];      }      for(int i=0;i<=n-1;i++)      {       num[i]=b[i]%c;      }      for(int i=0;i<=c-1;i++)      {        if(num[i]==0)        {         for(int p=0;p<=i;p++)          {           cout<<p+1<<" ";          }          cout<<endl;          break;        }        if(d[num[i]]==-1)        {         d[num[i]]=i;        }        else        {         for(int j=d[num[i]]+1;j<=i;j++)         {          cout<<j+1<<" ";         }         cout<<endl;         break;        }      }    }    return 0;}  

0 0
原创粉丝点击