1010 Radix (25)(25 分)(完成度:24/25)

目录

题目:

分析:

反思:

代码:


题目:

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

分析:

首先令a为已知进制的数,然后把a转换为10进制数

然后求出b可取的最小的进制(比b中最大的元素大1)

然后循环找符合条件的base

将n1逐位转换为当前的base进制数,并与b对应位进行比较

一旦有一位不同,则break并base++进入下一个base的比较判断

若所有位均相同,则输出

若base已经大于n1+1,可知求出来的数一定就是n1本身,base再怎么变大也不会改变

若此时还未找到符合题意的base,说明以后也找不到了,则输出Impossible

 

网上都用二分法防止超时,我的代码没有用二分法,是顺序往上++,但没有超时,是因为我不用把每个base对应的情况完全转换出来,我只需要转换几位也许就能跳出循环,进入下一次检验了。

反思:

改了三天,测试点7到现在没过去,显示答案错误,我很绝望

1、最大的进制不局限于36

2、转化为十进制数可能产生溢出

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
	string a, b;
	unsigned long long n1 = 0, n2 = 0, tag, radix, base;
	long long i = 0, j;
	char c;
	int over = 0;
	cin >> a >> b >> tag >> radix;
	if (tag == 2)swap(a, b);//令a为已知基数的数
	for (i = 0; i < a.length(); i++)//将a转换为10进制数n1
	{
		if (isdigit(a[i]))n1 = a[i] - '0' + n1 * radix;
		else n1 = a[i] - 'a' + 10 + n1 * radix;
	}
	base = isdigit(*max_element(b.begin(), b.end())) ? *max_element(b.begin(), b.end()) - '0' : *max_element(b.begin(), b.end()) - 'a' + 10;//求出b可取的最小基数-1
	while (!(i == -1 && n2 == 0))//检验目前的base是否满足条件
	{
		base++;
		n2 = n1;
		for (i = b.length() - 1; i >= 0; i--)//用n1转换为base进制,看与b是否相等
		{
			j = n2 % base;
			if (j < 10)c = j + '0';
			else c = j + 'a' - 10;
			if (c != b[i])break;
			n2 /= base;
		}
		if (base > n1 + 1)break;//当base大于n1+1后,无论base再怎么变大,得到的都是n1原数
	}
	if (base > n1 + 1)cout << "Impossible";//所以如果此时还不等于b,则说明不存在base使两数相等
	else cout << base;
	return 0;
}

下面这一版是考虑了a溢出直接输出Impossible的代码,还是不对,我要崩溃了 

#include
#include
#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
	string a, b;
	unsigned long long n1 = 0, n2 = 0, tag, radix, base;
	long long i = 0, j;
	char c;
	cin >> a >> b >> tag >> radix;
	if (tag == 2)swap(a, b);//令a为已知基数的数
	for (i = 0; i < a.length(); i++)//将a转换为10进制数n1
	{
		j = isdigit(a[i]) ? a[i] - '0' : a[i] - 'a' + 10;
		if (radix > 40)if (n1 > (ULLONG_MAX - j) / radix) { n1 = 0; break; }//如果a溢出则记n1=0并跳出
		n1 = j + n1 * radix;
	}
	if (b.front() == '0')b.erase(b.begin(), b.begin() + 1);//删除b开头的0(如果有的话)
	c = *max_element(b.begin(), b.end());//记录b中ascll码最大的元素
	base = isdigit(c) ? c - '0' : c - 'a' + 10;//求出b可取的最小基数-1
	while (!(i == -1 && n2 == 0) && n1)//检验目前的base是否满足条件
	{
		base++;
		n2 = n1;
		for (i = b.length() - 1; i >= 0; i--)//用n1转换为base进制,看与b是否相等
		{
			j = n2 % base;
			c = (j < 10) ? j + '0' : j + 'a' - 10;
			if (c != b[i])break;
			n2 /= base;
		}
		if (base > n1 + 1)break;//当base大于n1+1后,无论base再怎么变大,得到的都是n1原数
	}
	if (n1 == 0 || base > n1 + 1)cout << "Impossible";//所以如果此时还不等于b,则说明不存在base使两数相等,a溢出也输出impossible
	else cout << base;
	return 0;
}

 

 

你可能感兴趣的:(PAT甲级)