Uva 113 Power of Cryptography
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=49
二分答案。
在计算mid^k时,可以加个优化:如果计算到某一次方时位数超过了p的位数,直接舍弃。
刚发现 itoa 不是标准库的函数,有意思的是atoi atof……都是标准库函数。(为什么有atoi,却没有itoa)
# include <stdio.h> # include <string.h> typedef long long int LL; int n; char p[105]; char kn[205]; int plen; int getIntLen(int mid) { int ret = 0; while (mid > 0) { ++ret; mid /= 10; } return ret; } void strrev(char *str) { int half = plen / 2; for (int i = 0; i < half; ++i) { int ch = str[i]; str[i] = str[plen-1-i]; str[plen-1-i] = ch; } } int check(int mid) { memset(kn, 0, sizeof(kn)); kn[0] = 1; int len = getIntLen(mid); if (n*len+1 <= plen) return -1; if ((len-1)*n+1 > plen) return 1; for (int i = 0; i < n; ++i) { LL carry = 0; for (int j = 0; j < 205; ++j) { LL tmp = carry + kn[j]*(LL)mid; kn[j] = tmp%10; carry = tmp/10; } for (int j = 204; j >= 0; --j) { if (kn[j] != 0) { if (j+1 > plen) return 1; break; } } } int i; for (i = 204; kn[i] == 0; --i) ; if (i+1 < plen) return -1; kn[i+1] = '\0'; while (i >= 0) kn[i--] += '0'; strrev(kn); return strcmp(kn, p); } void solve(void) { plen = strlen(p); int high = 1000000000; int low = 1; int mid; while (low <= high) { mid = (high-low)/2 + low; int tmp = check(LL(mid)); if (tmp < 0) low = mid+1; else if (tmp > 0) high = mid-1; else {printf("%d\n", mid); return ;} } } int main() { while (scanf("%d%s", &n, p) != EOF) { solve(); } return 0; }