POJ 2356-Find a multiple(抽屉原理)

Find a multiple

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 10270 Accepted: 4379 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个自然数(即正整数)(N <= 10000)。每个数字都不大于15000。这个数字不一定是不同的(因此,可能会有两个或多个相等)。您的任务是选择一些给定的数字(1 <=少数<= N),以便所选数字的总和是N的倍数(即N * k =(所选数字的总和)对于某些自然数k)。
输入值
输入的第一行包含单个数字N。接下来的N行中的每一行都包含给定集合中的一个数字。
输出量
如果您的程序确定找不到目标数字集,则应在输出中打印单个数字0。否则,应在第一行中打印所选数字的个数,然后打印所选数字本身(在单独的位置)每行)以任意顺序排列。

如果具有所需属性的一组数字以上,则应仅将其中一个(最好是您最喜欢的)打印到输出中。
样本输入
5
1个
2
3
4
1个
样本输出
2
2
3

题目大意:给出一个数n,接下来有n个数,判断n个数中是不是有一串数字的和是n的倍数,如果是,则输出选择数字的个数,下面再输出所选择的数,如果没有满足条件的集合,则输出0。

解题思路:我一开始没有想到,这道题是抽屉原理,即:n+1个物品放入n个抽屉,则至少有一个抽屉里的物品不少于两件,这道题又是怎么运用的呢,我们设一个前缀和数组1+2+3…+n,如果1+…+到某项的值恰好是n的倍数,则直接输出即可。如果不是则对每一项取模,如果有两项的模是相等的,则根据同余定理,他们的差一定是n的倍数,所求的答案就是他们中间连续的数字,题目又说如果不存在则输出0,其实经过分析我们可以发现,**这道题是一定存在解的!!**如果答案不是前n项的和,则答案出在第一项和第n-1项其中连续的数字,就相当于把n个物品放入n-1个抽屉,必定有一个抽屉不少于两件物品,即必定有两个数%n是相等的,也就说明这两个数是同余的,即答案一定存在。AC代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int _max=2e5;
int mod[_max],sum[_max]={0},a[_max];
int main()
{
	int n;
	cin>>n;
	memset(mod,-1,sizeof mod);//存放余数的位置
	for(int i=1;i<=n;i++)
	  cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		sum[i]=sum[i-1]+a[i];
		if(sum[i]%n==0)
		{
			cout<<i<<endl;
			for(int j=1;j<=i;j++)
			  cout<<a[j]<<endl;
			break;  
		}
		if(mod[sum[i]%n]!=-1)//如果位置不是-1则说明这个数之前出现过了。
		{
      	cout<<i-mod[sum[i]%n]<<endl;
      	for (int j=mod[sum[i]%n]+1;j<=i;j++)
         	cout<<a[j]<<endl;
         break;
        }
      mod[sum[i]%n]=i;
	}
	return 0;
}
posted @ 2020-03-11 17:24  Hayasaka  阅读(65)  评论(0编辑  收藏  举报