poj 2356 Find a multiple

这是一道简单的对鸽笼原理的运用;

题意:给出N个数,从中选出若干个数使得它们的和为N的倍数。

有一种简单的方法如下:

虽然题目没限制怎样选,但是我们可以证明:存在若干个这样的连续数,它们的和是N的倍数。为此,我们可以考察和Sk =a1+a2+...+ak.如果存在一个Sk是N的倍数,那么把前K个数选出来就可以了。否则所有N歌Sk除以N的余数只有1,2,3,4...N-1;这n-1种可能(n-1个盒子),由基本原理 知,必然有两个不同的和Si和Sj(i<j)除以N的余数相同,所以

Sj -Si = ai+1 + .... aj 是N的倍数;

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#include<string>
#define LL long long
using namespace std;

int main(  )
{
    int num[10024];
    int N,a[10024];
    while( scanf( "%d",&N )==1 ){
        int sum = 0,flag = 0;
        memset( num , 0, sizeof( num ) );
        for( int i = 1 ; i <= N ; i++ ){
             scanf( "%d",&a[i] );
             if( flag ) continue;
             sum += a[i];
             int t =  sum % N;
             if( t== 0 ){
                 flag = 1;
                 printf( "%d\n",i );
                 for( int j = 1 ; j <= i; j++  )
                      printf( "%d\n",a[j] );        
             }
             else if( num[t] == 0 )
                      num[t] = i;
             else{
                 flag = 1;
                 printf( "%d\n",i - num[t] );
                 for( int j = num[t]+1 ; j <= i ; j ++ )
                           printf( "%d\n",a[j] );
            }
        }
    }
    //system( "pause" );
    return 0;
}

 

posted @ 2012-07-27 10:27  wutaoKeen  阅读(257)  评论(0)    收藏  举报