POJ 2356 Find a multiple [抽屉原理]

题意:

给定n个正数,请你从中找出若干个数,其和刚好是n的倍数。


思路:

抽屉原理。

sum[0]=0;

sum[i]=(a[1]+a[2]+a[3]...a[i])%n;

如果存在i>0 使得sum[i]=0;则直接输出a[1],a[2],,....a[i]即可满足题意。

如果不存在,考虑sum[ j ]-sum[ i ]=a [ i+1 ],a[ i+2 ]....a[ j ]。

即如果存在sum[ j ]-sum[ i ]==0,则输出 a [ i+1 ],a[ i+2 ]....a[ j ] 即可。

接下来用抽屉原理证明 i , j 必然存在。


抽屉原理:

如果将大于n个数量的物品放入n个抽屉,则必然存在某个抽屉放了大于1个物品。


因为sum [ i ] 的值只能是1,....n-1.sum [ i ]的数量有n个。

所以由抽屉原理可知,必然存在某两个sum [ i ] 值一样。


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#define llong long long
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define Abs(a) ((a)>0?(a):-(a))
#define Mod(a,b) (((a)-1+(b))%(b)+1)
using namespace std;
int n,m;
const int N=10005;
const int M=35;
const int inf=99999999;
int sum[N],a[N],has[N];
int main()
{
	scanf("%d",&n);
	memset(has,-1,sizeof(has));
	has[0]=0;
	int l,r;
	for(int i =1;i<=n;i++)
	{
		scanf("%d",a+i);
		sum[i]=(sum[i-1]+a[i])%n;
		if(has[sum[i]]==-1)
		{
			has[sum[i]]=i;
		}
		else
		{
			l=has[sum[i]];
			r=i;
		}
	}
	printf("%d\n",r-l);
	for(int i=l+1;i<=r;i++)
	{
		printf("%d\n",a[i]);
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值