The ? 1 ? 2 ? ... ? n = k problem
The ? 1 ? 2 ? ... ? n = k problem |
The problem
Given the following formula, one can set operators '+' or '-' instead of each '?', in order to obtain a given k
? 1 ? 2 ? ... ? n = k
For example: to obtain k = 12 , the expression to be used will be:
- 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12
with n = 7
The Input
The first line is the number of test cases, followed by a blank line.
Each test case of the input contains integer k (0<=|k|<=1000000000).
Each test case will be separated by a single line.
The Output
For each test case, your program should print the minimal possible n (1<=n) to obtain k with the above formula.
Print a blank line between the outputs for two consecutive test cases.
Sample Input
2 12 -3646397
Sample Output
7 2701
方法 :
对于 整数k,如果k>0,在其求出的等式两边同乘-1,就得到-k的等式。
所以 只需考虑k>0的情况。
1.先求出sum = 1+2+...+n >= k 的第一个n值。
所求min_n一定小于n值。
2.求d = sum-k的值,如果d是偶数,则可以通过sum-d得到k,即在1...n中找到和为d/2的组合(该组合一定存在),把它们前面的+改为-,就得到和k。
如果的d是奇数,则要继续用sum加上n以后的数(n+1,n+2...)知道d为偶数。
其实 ,如果d是奇数,最多只需再加两个数,就一定能得到偶数d:
如果 n+1是奇数,则d+n+1是偶数;
如果 n+1是偶数,则n+2是奇数,d+n+1是奇数,d+n+1+n+2就是偶数。
3.返回加到的最后的n。
代码 :
#include int candiate(int k) { int n, s; s = 0; for(n = 1; ; n++){ s += n; if(s >= k) break; } s -= k; while(s & 1){ n++; s += n; } return n; } int main() { int t, k, n; scanf("%d", &t); while(t-- > 0){ scanf("%d", &k); if(k < 0) k = -k; printf("%d\n", candiate(k)); if(t != 0) printf("\n"); } return 0; }