URAL 1032. Find a Multiple

  

这题嘛……刚开始写的超时的程序。后来发现是用鸽笼原理来做的。

总共有N个数。

输入的数据存为 a[1] a[2] .........a[N]

令 b[n]=(a[1]+a[2]+a[3]+...+a[n])%N           (n=1,2,3,...,N)

b[0]=0;

首先,b[n]都是N的余数。总共有N个取值(0,1,2,...,N-1)

而 b[0],b[1],b[2],...,b[N]共有N+1个数。

根据鸽笼原理,必存在 i <  j  使得 b[ i ]=b[ j ] ,即前 i 个数的和的余数等于前 j 个数的和的余数,则从 第 i+1个数到第 j 个数的和的余数=0;

则 a[ i+1],a[ i+2],...,a[ j ]  即为所求。

代码如下

int a[10001];
int b[10001];
int c[10000];
int N;

int main(void)
{ 
	while(cin>>N){		
		//输入
		memset(c,0,sizeof(c));
		b[0]=0;c[0]++;
		for(int i=1;i<=N;i++){
			scanf("%d",&a[i]);
			b[i]=(b[i-1]+a[i])%N;
			c[b[i]]++;
		} 
		int T=0;
		//找到相同的余数值 
		int same,l=-1,r=-1;
		for(int i=0;i<10000;i++){
			if(c[i]>=2){
				same=i;//存在两个余数都为i 
				break;
			}
		}
		//找到l和r
		for(int i=0;i<=N;i++){//搜索所有的余数 
			if(b[i]==same){//如果余数对了,则记录 i 
				if(~l) {
					if(~r) break;
					else r=i;
				}
				else l=i;
			}
		}
		//输出 
		if(~l&&~r){
			printf("%d\n",r-l);
			for(int j=l+1;j<=r;j++){
				printf("%d\n",a[j]);
			}
		}
		else{
			printf("%d\n",0);
		}
	}
return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值