Uva 10025 The ? 1 ? 2 ? ... ? n = k problem

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=966

对于k<0,可以将加号变为减号,减号变为加号,这样和原问题是等价的,所以只需要考虑k>=0的情况。

可以证明这样一个结论:对于任意x in [1, n*(n+1)/2],可以用1...n这n个数的若干个数的和构成。

这样对与k>=0,题目就化为了求最小的 n 满足 n*(n+1)/2>= k,即min{n|n*(n+1)>=k},显然复杂度过得去。

特别要注意题目要求每两个输出之间有一个空行。

# include <stdio.h>
# include <math.h>

int ic;
int M;

int main()
{
    scanf("%d", &ic);
    for (int i = 0; i < ic; ++i) {
        if (i) printf("
");
        scanf("%d", &M);
        if (M < 0) M = -M; 
/*
这个递增的方法是看到的,虽然这道题复杂度要求不高,这个方法的复杂度略高,特别是如果样例在10^5以上
        for (int n = 1; ; ++n) {
            long long int N = n*(n+1)/2;
            if (N >= M && N%2 == M%2) {
                printf("%d
", n);
                break;
            }
        } 
 */

// 这个复杂度在O(1)级别
        int n = (int)floor(sqrt(M*2.0)*0.5-0.5) - 1;
        long long int N = 0;
        while (n <= 0) ++n;
        while (1) {
            N = ((long long int)n)*(n+1)/2;
            if (N >= M && N%2==M%2) {
                printf("%d
", n);
                break;
            }
            ++n;
        }
    }
    
    return 0;
}
    
原文地址:https://www.cnblogs.com/txd0u/p/3395542.html