hdu 4430二分枚举

枚举r,二分K就可以了,不过还是需要注意细节,比较数据类型之类的,不然容易错。

/*
 * hdu4430/win.cpp
 * Created on: 2012-10-26
 * Author    : ben
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
typedef long long LL;

LL judge(LL n, int r, int k) {
    LL sum = 0, t = 1;
    while(r--) {
        t *= k;
        sum += t;
        if(sum > n) {
            return 1;
        }
    }
    if(sum == n || sum == n - 1) {
        return 0;
    }
    if(sum > n) {
        return 1;
    }
    return -1;
}

int bsearchk(int r, LL n) {
    int low = 1, high = 10000000;
    while(low <= high) {
        int mid = (low + high) / 2;
        LL ret = judge(n, r, mid);
        if(ret > 0) {
            high = mid - 1;
        }else if(ret == 0) {
            return mid;
        }else {
            low = mid + 1;
        }
    }
    return -1;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    LL n;
    while(scanf("%I64d", &n) == 1) {
        LL ansrk = n - 1;
        LL ansr = 1, ansk = n - 1;
        for(int r = 2; r <= 70; r++) {
            int k = bsearchk(r, n);
            if(k >= 2) {
                LL temp = (LL)r * k;
                if(temp < ansrk) {
                    ansrk = temp;
                    ansr = r;
                    ansk = k;
                }
            }
        }
        printf("%I64d %I64d\n", ansr, ansk);
    }
    return 0;
}
posted @ 2012-10-26 23:01  moonbay  阅读(172)  评论(0编辑  收藏  举报