UVA 10025 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有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
", num);
	if (t)
	    printf("
");
    }
    return 0;
}


原文地址:https://www.cnblogs.com/aukle/p/3228711.html