UVa_OJ 10025 ?1?2...?n=k问题

本文介绍了一种解决特定数学问题的算法思路,通过逆向思维简化问题,提出了一种有效的判断条件,并给出了实现该算法的C语言代码。

这道题大意是这样的:

给你从1到n的n个数,要求使 ?1?2...?n=k 成立,其中?表示正负号未定,在这样的情况下,求最小的n是多少。


这道题如果顺着思考,确实不太好想,但如果逆向思考的话,会有出其不意的效果:

假设 存在一个这样的最小数 n 使得(1)式:  ?1?2...?n=k  成立,那么对应的一定有 (2)式:  1+2+...+n >=k 成立 ;这是肯定的,因为在(1)式左边有正有负,而(2)式对应的全是正号(即使(1)式左边也全是正号,那么(2)式=k,符合条件 >= ,即依然成立);

现在让我们来考虑 (1)式和(2)式的区别,设(1)式左边部分的和为sum1,(2)式左边部分的和为sum2,那么可得: sum2-sum1 = sum2 - k = W,其中这个W(也就是它们的差)一定是个偶数,至于为什么一定是偶数,原因如下:


设 (1)式左边部分为负数的某一项为  ( -) i ,那么在(2)式中对应的就为 (+)i,因为 (+)i - (-) i = 2i,很显然 2i 是偶数, 所以 sum2 - sum1 = 偶数。 


到这里,其实就没必要再往下继续思考了,假如我们用暴力求解的话,这就是我们的判决条件了。


AC代码如下:

#include<stdio.h>
int main(){
	#ifdef LOCAL
	freopen("10025_input.txt","r",stdin);
	freopen("10025_output.txt","w",stdout);
	#endif
	int k,i,j,CASENUM,sum;
	scanf("%d",&CASENUM);
	for(i=0;i<CASENUM;i++){
		scanf("%d",&k);
		if(k<0)
			k*=-1; 
		j=0;
		sum=0;
		do{ 
			sum+=(++j);
		}while(!(sum>=k&&(sum-k)%2==0)); 
		printf("%d\n",j);
		if(i<CASENUM-1)
			printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值