【每日一题(36)】Sum POJ-1844 (趣题)

Sum POJ-1844

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.
Input
The only line contains in the first line a positive integer S (0< S <= 100000) which represents the sum to be obtained.

Output

The output will contain the minimum number N for which the sum S can be obtained.

Sample Input

12

Sample Output

7

Hint

The sum 12 can be obtained from at least 7 terms in the following way: 12 = -1+2+3+4+5+6-7.

题解

题目大意是,给定一个数字N,让你求出一个最小的S,让1+2+…+S变换某些数字的符号,使得1 ± 2 ± 3 ± … ± S == N
所以样例中给出N为12,存在最小S为7,使得1-2+3+4+5-6+7=12;


我们把累加的结果记为Sum,累加的数字个数记为n,变换符号的数字称为ki
仔细观察我们会发现

当我们减去一个数字,Sum就会减去这个数字的两倍
即 1+2+3+…+k+…+n = Sum
当我们把k符号变号 Sum’ = Sum - 2k;
举例:1 + 2 + 3 + 4 = 10 → 1 + 2 - 3 + 4 = 4
我们把3变成了负的,于是10变成了 10 - 2*3 = 4
这是在一个数符号变负的情况。


同样的,我们可以推广出多个数字符号改变的情况

若将 k1,k2…ki的符号都变成负号
Sum’ = Sum - 2*(k1+k2+…+ki);
例子见题目案例;


所以我们可以把题目要求分为两种情况


1 + 2 + … + S == N;
即累加刚好等于题目所给N



Sum > Sum’,即需要在某些数字前变换负号。
因为我们已经知道Sum - Sum’ 会是某个数字或某些数字的两倍
即Sum - Sum’一定是偶数。
反过来,如果Sum - Sum’是偶数,我们总能在1到S中找到一个或一些数字等于(Sum - Sum’)/2
于是,我们把这个或这些数字符号变负即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
using namespace std;
int main()
{
int n,sum = 0,i = 0;
cin >> n;
while(++i){
sum += i;
if(n == sum|| (n < sum && (sum - n)%2 == 0)){
cout << i << endl;
break;
}
}

return 0;
}