题意:给出S(S>0)位置某一个到迭代,问是否存在N使得1~N这些数字相加减(每个数字只使用一次)能得到S。
分析:1+..+N<S, 一定无法构成,N需要增加1+..+N=S直接输出N
1+..+N>S需要把一些数字改成负的,改1则总和减少2,改2则总和减少4……用这种方式可以构成所有的0到1+..+N之间的与1+..+N差为偶数的数字。如果差小于等于N*2则可以直接通过一个数字的变号得到,如果大于N*2则先将N变号,然后迭代为N-1的子问题。一定某一个位置之后可以用一个数字的变号解决,因为一直迭代下去,变成负号的数字过多,会造成式子计算结果为负数。
所以只要总和-S为偶数即可构成,如果不是偶数则N需要增加。
大牛的证明:
一:sum一定要大于或等于输入的S.(等于时就已经找到了答案)
小于的话就算全做加法运算也不能达到S。
二:在满足第一条的情况下,注意一定要满足第一条后
第一次碰到(sum - S ) % 2 == 0
这里( sum = 1 + 2 + .... + i )这时的i就是答案。
证明如下:
1:若res是奇数,就说明res = ( 1 + 2 + ... + i )- S 是奇数
也就是说无论你怎么改变sum( sum = 1 + 2 + .... + i )的表达式
(当然是通过改变其中的加号为减号)也无法让res为0
举个例子吧:S = 5, sum = 1+2+3 = 6, res = 6 - 5 = 1;
无论改变(1+2+3)中的加号也没用,这是因为你在sum中改变一个加号为减号
时它的值就一定减少了一个偶数值(这是显然的)sum-S仍然为奇数
2:令res = sum - S,则res一定是0,2, 4, 6....中的一个
下面说明总可以通过改变sum表达式中的某几个加号为减号使得res为0
当k = 0的情况就不用说明了吧, 假设2k表示res 显然k = 1 2 3 4...
当k = 1 时可以通过把sum( sum = 1 + 2 + ... + i )
Sum
-
描述
-
Consider the natural numbers from 1 to N. By associating to each number a sign (+ or -) and calculating the value of this expression we obtain a sum S. The problem is to determine for a given sum S the minimum number N for which we can obtain S by associating signs for all numbers between 1 to N.
For a given S, find out the minimum value N in order to obtain S according to the conditions of the problem.-
输入
-
The input consists N test cases.
The only line of every test cases contains a positive integer S (0< S <= 100000) which represents the sum to be obtained.
A zero terminate the input.
The number of test cases is less than 100000.
输出
- The output will contain the minimum number N for which the sum S can be obtained. 样例输入
-
3 12 0
样例输出
-
2 7
来源
- POJ
-
The input consists N test cases.
#include<stdio.h>
int main()
{
int sum,s,i;
while(~scanf("%d",&s),s)
{
sum=i=0;
while(sum<s||(sum-s)%2==1)
{
sum += ++i;
}
printf("%d\n",i);
}
return 0;
}