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

 

posted @ 2013-10-29 17:11  努力变瘦  阅读(148)  评论(0编辑  收藏  举报