枚举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; }