zoukankan      html  css  js  c++  java
  • PAT (Advanced Level) Practice 1010 Radix (25分) (进制转换 longlong溢出 二分查找)

    1.题目

    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 N​1​​ and N​2​​, 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
    

    2.题目分析

    开始用正常思路先将一个转为10进制,然后不停转换为其它进制与n2比较,结果测试点 7、10错误

    之后得知存在long long溢出以及二分问题,于是改进

    https://blog.csdn.net/sheepyWYY/article/details/54576790?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

    3.代码

    原版本(测试点7 10 错误)

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    long long  changea(string c,int m)
    {
    	long long num = 0;
    	for (int i = 0; i < c.length(); i++)
    	{
    		if (islower(c[i]))  num += (c[i] - 'a' + 10) * pow(m, c.length() - 1 - i); //如果是字母的话就+10,因为a代表10
    		else if (isupper(c[i])) num += (c[i] - 'A' + 10)*pow(m, c.length() - 1 - i);
    		else if (isdigit(c[i]))num += (c[i] - '0')*pow(m, c.length() - 1 - i);//如果是数字就直接乘
    	}
    	return num;
    }
    string changeb(long long  num,int n)
    {
    	string answer = "";
    	int out[100];
    	int s = 0;
    	while (num > 0)
    	{
    		out[s++] = num%n;
    		num /= n;
    	}
    	if (n <= 9)//将变为的进制<=9
    	{
    		for (int i = s - 1; i >= 0; i--)
    			answer += (out[i] + '0');
    	}
    	else
    	{
    		for (int i = s - 1; i >= 0; i--)
    		{
    			if (out[i] >= 10)answer += (out[i] - 10 + 'a'); 
    			else answer += (out[i] + '0');
    		}
    	}
    	return answer;
    }
    
    int main()
    {
    	string n1, n2;
    	long long tag, radix;
    	cin >> n1 >> n2 >> tag >> radix;
    	if (tag == 2)
    		swap(n1, n2);
    	long long num = changea(n1, radix);
    
    	for (int i = 2; i < 10000; i++)
    	{
    		string temp = changeb(num, i);
    		if (temp == n2) { printf("%lld", i); return 0; }
    	}
    	printf("Impossible
    ");
    }

    改进:

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    int Alpha2int(char c) { //数字转换
    	if (int(c) >= int('0') && int(c) <= int('9')) {
    		return (int(c) - 48);
    	}
    	else
    		return int(c) - 87;
    }
    long long  changea(string c,int m)
    {
    	long long num = 0;
    	for (int i = 0; i < c.length(); i++)
    	{
    		if (islower(c[i]))  num += (c[i] - 'a' + 10) * pow(m, c.length() - 1 - i); //如果是字母的话就+10,因为a代表10
    		else if (isupper(c[i])) num += (c[i] - 'A' + 10)*pow(m, c.length() - 1 - i);
    		else if (isdigit(c[i]))num += (c[i] - '0')*pow(m, c.length() - 1 - i);//如果是数字就直接乘
    		if (num < 0)return -1;
    	}
    	return num;
    }
    long long changeb(long long  start,long long end,long long num ,string n2)
    {
    	long long mid = (start + end) / 2;
    	long long temp = changea(n2, mid);
    	long long result = -1; 
    	if (start <= end) 
    	{
    		if (temp == -1 || temp > num) 
    		{//溢出减少Radix
    			result = changeb(start, mid - 1, num, n2);
    		}
    		else if (temp < num)
    		{
    			result = changeb(mid + 1, end, num, n2);
    		}
    		else 
    		{
    			result = mid;
    		}
    	}
    	return result;
    }
    
    int main()
    {
    	string n1, n2;
    	long long tag, radix;
    	cin >> n1 >> n2 >> tag >> radix;
    	if (tag == 2)
    		swap(n1, n2);
    	long long num = changea(n1, radix);
    	long long max = num + 1;
    	long long min = 2;
    	for (int i = 0; i < n2.size(); i++) 
    	{ 
    		if (Alpha2int(n2[i]) >= min)
    			min = Alpha2int(n2[i]) + 1; //要加1
    	}
    		long long result = changeb(min, max,num,n2);
    		if (result !=-1) { printf("%lld", result); return 0; }
    	printf("Impossible
    ");
    }
  • 相关阅读:
    [BZOJ4876][ZJOI2017]线段树
    [FJOI2016]建筑师(斯特林数)
    WC2018伪题解
    [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
    [BZOJ2594][WC2006]水管局长加强版(LCT+Kruskal)
    [洛谷3796]【模板】AC自动机(加强版)
    [洛谷3808]【模板】AC自动机(简单版)
    [BZOJ3261]最大异或和
    [BZOJ3439]Kpm的MC密码
    [POI2006]Periods of Words
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12788814.html
Copyright © 2011-2022 走看看