PAT甲级1010

1010. Radix (25)
时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is "yes", if 6 is a decimal number and 110 is a binary number.


Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.


Input Specification:


Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a-z} where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number "radix" is the radix of N1 if "tag" is 1, or of N2 if "tag" is 2.


Output Specification:


For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print "Impossible". If the solution is not unique, output the smallest possible radix.


Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:

Impossible

以上是题目

以下是代码

#include
#include
#include
#include


using namespace std;


int compare_value(vector< int> a , long long radix, long long src_value){
     long long dst_value = 0;
     int m = 0;
     int cnt = a. size();
     for( int i = cnt- 1; i>= 0; i--){
        dst_value += a[i]* pow(radix,m);
         if(dst_value > src_value){
             return 1;
        }
        m++;
    }
     if(dst_value == src_value)
         return 0;
     else
         return - 1;
}


long long result(vector< int> a, long long radix)
{
     int cnt = a. size();
     int n = cnt;
     long long sum = 0;
     for( int i= 0;i
        sum +=a[i]* pow(radix,n- 1);
        n--;
    }
     return sum;
}

long long search_radix( long long min_radix, long long max_radix, vector< int>a, long long src_value){

     long long mid_radix = 0;
     int value;

     while(min_radix <= max_radix){
     mid_radix = (min_radix+max_radix)/ 2;
     value = compare_value(a,mid_radix,src_value);
         if(value == 1)
            max_radix = mid_radix - 1;
         else if(value == 0)
             return mid_radix;
         else
            min_radix = mid_radix + 1;
    }
     return - 1;
}


int main(){
    string a,b;
    string src_str,dst_str;
     long long src_value,dst_value;
    vector< int> src_num,dst_num;
int type;
     long src_radix,dst_radix;
     int max_num= 0;
     long long max_radix;

    cin >> a >> b >> type >> src_radix;
if(type == 1){
        src_str = a;
        dst_str = b;
    }
     else {
        src_str = b;
        dst_str = a;
    }
     for(string::iterator i = src_str. begin();i!=src_str. end();i++){
         if(*i>= 'a')
            src_num. push_back(*i- 87);
         else
            src_num. push_back(*i- '0');
    }
     for(string::iterator i= dst_str. begin();i!=dst_str. end();i++){
         if(*i>= 'a'){
            dst_num. push_back(*i- 87);
             if(*i- 87 > max_num)
                max_num = *i - 87;
        }
         else {
            dst_num. push_back(*i- '0');
             if(*i- '0' > max_num)
                max_num = *i- '0';
        }
    }
     if(max_num == 0)
        max_num++;
    src_value = result(src_num,src_radix);
     if(src_value > max_num)
        max_radix = src_value;
     else
        max_radix = max_num+ 1;
    dst_radix = search_radix(max_num+ 1,max_radix,dst_num,src_value);
     if(dst_radix == - 1)
        cout << "Impossible" << endl;
     else
        cout << dst_radix << endl;
     return 0;
}

小结:这个题目令我改的有一点痛不欲生,代码修修补补也惊人的超过了100行,不想再重写了,就那样吧。简单来说说几个要点:(1)大家都觉得这个题目比较坑,最大的坑点是没有给出radix的具体范围,天知道给出的数据的值范围是多大,看了看网上大家的答案,都用了long long来存数,其实2^63-1我觉得真要弄起来也是可以不够用的=-=,还好测试用例没这么变态,都过了。(2)0的radix最小是2不是1。(3)暴力查找据说会超时,用二分法找,这时要确定max_radix与min_radix,min_radix为要查找radix的那组10个字中最大的字的值+1,max_radix是已给出radix的那组数据的真实值src_value和min_radix中最大的那个值(想想很容易理解,随便一个不为0的数乘以大于src_value的数的值肯定>src_value,不用比了,而max_radix >=min_radix是必须的。。。),这里也隐含的解决了 110 6 1 2 这个例子的值是7而不是8,9,10 的问题。(4)溢出问题,在用二分法时必须考虑每次通过mid_radix算出来的值dst_value是否溢出后才能和src_value比较然后确定下一轮查找范围,这里我觉得不能单单通过判断得到的dst_value的最终值的正负来判断溢出,毕竟值太大,很可能dst_value的值为正仍然溢出。。。,所以在上面的compare_value中每次判断一下累加时的dst_value中间值的大小来判断溢出。

大概就是这些,脑壳疼。

你可能感兴趣的:(PAT)