Find a multiple
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 9546 | Accepted: 4078 | Special Judge |
Description
The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more of them will be equal). Your task is to choose a few of given numbers ( 1 <= few <= N ) so that the sum of chosen numbers is multiple for N (i.e. N * k = (sum of chosen numbers) for some natural number k).
Input
The first line of the input contains the single number N. Each of next N lines contains one number from the given set.
Output
In case your program decides that the target set of numbers can not be found it should print to the output the single number 0. Otherwise it should print the number of the chosen numbers in the first line followed by the chosen numbers themselves (on a separate line each) in arbitrary order.
If there are more than one set of numbers with required properties you should print to the output only one (preferably your favorite) of them.
Sample Input
5
1
2
3
4
1
Sample Output
2
2
3
思路:
抽屉原理:
桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理。
先求出前i个数的和sum[i],然后一个for循环判断一下是否有sum[i]%n==0的情况,如果有,则输出a[1]到a[i]
如果没有:
那么sum[1]-sum[n]都满足sum[i]%n属于[1,n-1],这可以看成是有n-1个抽屉,n个苹果(sum[1到n],一共n个值,每个值%n后的结果会落到[1,n-1]区间,就算是前n-1个数%n的结果两两都不相等,也就是把前n-1个苹果放到n-1个抽屉里,那么sum[n]%n也一定会和前n个数中其中一个sum[i]%n的值相等的),则至少有两个sum值余n的结果是相同的。
(sum[i]%n=sum[j]%n,i!=j)
这样一来从第i+1个数到第j个数的和就肯定是n的倍数了,而且肯定存在。sum[j]至少比sum[i]大了一倍的n
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
const int N=10015,mod=32767;
int sum[N],a[N];
int main(){
int n,flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
if(sum[i]%n==0)flag=i;
}
if(flag){
printf("%d\n",flag);
for(int i=1;i<=flag;i++){
printf("%d\n",a[i]);
}
return 0;
}
int i,j;
flag=0;
for(i=1;i<n;i++){
for(j=i+1;j<=n;j++){
if(sum[j]%n==sum[i]%n){
flag=1;
break;
}
}
if(flag)break;
}
printf("%d\n",j-i);
for(int k=i+1;k<=j;k++){
printf("%d\n",a[k]);
}
}