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有1000000000.直接暴搜肯定跪。。 即肯定存在一定规律。。。
我们知道1- n个数的和可以表示为 n * (n + 1) / 2。。
再看样例中 输入12时。如果n为5 和为15, 15 - 12 = 3, 我们知道一个数m, +m 和 -m 相差 2 * m。一定是偶数。
那么15 - 12 = 3为奇数。 在1 - 5中 必然不可能找到一个数的两倍是3 所以不符合。 同理n为6 和为21.也不可以
而 n为7 时 和为 28。 28 - 12 = 16; 这时候 16 就满足 1 - n中 7 * 2 + 1 * 2了。所以就符合条件输出。。
因此。这个问题可以转换为。 求一个最小的n 。使得n的前n项和 n * (n + 1) / 2 - k 为偶数且大于等于 n的前n项和的两倍。。。
求n的时候可以直接暴力了。。因为估算一下,n只要枚举到5W 就能使得 n * (n + 1) / 2 > k 了。。。
#include <stdio.h> #include <string.h> #include <math.h> int t; int n; int num; int main() { scanf("%d", &t); while (t --) { scanf("%d", &n); for (int i = 1; i < 50000; i ++) { long long sum = (i * (i + 1)) / 2; if (sum >= n && (sum - n) % 2 == 0 && (sum - n) <= i * (i + 1)) { num = i; break; } } printf("%d\n", num); if (t) printf("\n"); } return 0; }