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
乍一看没思路,写几个试试
num maxsum
1 1
2 3
3 6
4 10
5 15
6 21
7 28
感觉12<15因该是5个数字表示可是它是7个
于是发现问题,一个数字n能否用m个数字的表示条件是首先m个数字全部加起来大于n,全取+;
如果全部加起来大于n还要满足第二个条件就是m个数字和减去n必须是偶数,拿12做例子,5个数字和为15,要编程12必须-3,由于之前都是+现在必然要把某几个数字改为-,
+x变为-x,少了2x,所以减少的只能是偶数,所以5个不行6个是21不行所以是7个,然后负数相当于原来正负号取反,
0比较特殊1-2+3;
规律找到了还是错了很多次,原因就是实数的精度问题;
m*(m+1)/2=n
m=(-1+sqrt(1+4*2n))/2 wrong了好几次,估计由于精度丢失导致有几个数字的m算出来比实际的大╮(╯▽╰)╭。
办法就是算出的值让他略小于实际m值;
可以m=sqrt(2*n); 忽略m+1为m;或者算出的m减去一个小的常数,本人-10过了,当然-10之后小于0要重新赋值。
#include<stdio.h>
#include<math.h>
void main()
{int m,n,t,s;
scanf("%d",&t);
while (t--)
{scanf("%d",&n);
if (n==0) m=3;
else
{
if (n<0) n=-n;
m=(-1+sqrt(1+8*n))/2-10;
if (m<1) m=1;
s=m*(m+1)/2;
while ((s<n)||((s-n)%2==1))
{++m;s=m*(m+1)/2;}
}
printf("%d\n",m);
if (t) printf("\n");
}
}