uva 10025 - The 1 2 ... n = k problem

就是给出一个数,最少能用多少个数表示。

每个数前面为正号或者负号。

可以只考虑正数(输入的负数当正数也行。算出正数的符号全变就行,数字不会改变);

先把前n项和的值存入数组,直到大于1e9,题目给的最大值。

然后判断所给的数字在前k与k+1项的和之间,然后判断与小的那个差,若为奇数,则最少数+1,直到为偶数。

因为每次将一个负号变成正号的时候,是减去两倍的这个数,必为偶数。

还有,注意为0的特殊情况。

#include<cstdio>
#include<cstring>
const int MAXN=1e6;
int store[MAXN]={0};
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int i;
    for(i=1;store[i-1]<=1e9;i++){
        store[i] = store[i-1]+i;
    }
    store[i]=store[i-1]+i+1;
    int T;
    scanf("%d",&T);
    while(T--){
        int k,temp;
        scanf("%d",&k);
        if(k==0) {printf("3\n",k);if(T)printf("\n");continue;}
        if(k<0) k= -k;
        int head=0,tail=i,middle=(head+tail)/2;
        for(;!(store[tail-1]<k&&k<=store[tail]);){
            if(k>=store[head]&&k<store[middle]) tail=middle;
            else if(k>store[middle]&&k<=store[tail]) head=middle;
            else if(k==store[middle]){temp=middle;break;}
            middle=(head+tail)/2;
            temp = tail;
        }
        while((store[temp]-k)%2!=0) temp++;
        printf("%d\n",temp);
        if(T) printf("\n");
    }
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值