题意:给定一个数n,问其由1 2 3 4 .......k中间加上加号或者减号来表示的最小k值。比如12 = -1+2+3+4+5+6-7。
思路:一开始直接用类似背包的思路,TLE。实际上,找到第一个k,使得前k项和S≥n,在前面减去(S-n)/2即可。所以对S-n的奇偶性进行分类,如果是偶数,则可以。如果S-n是奇数,那么再看看k是奇数还是偶数,决定了需要再加上一个还是两个数才能使得S-n变成偶数。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
#define clc(s,t) memset(s,t,sizeof(s))
#define INF 0x3fffffff
int n;
int main(){
int i,j;
scanf("%d",&n);
i = (int)sqrt(n*2.);
for(j = i;;j++){
if(j*(j+1)/2>=n)
break;
}
if((j*(j+1)/2-n) % 2 == 0){
printf("%d\n",j);
}else{
if(j&1)
printf("%d\n",j+2);
else
printf("%d\n",j+1);
}
return 0;
}