PAT甲题 1010 Radix


为了便于自己复习,就将PAT的各题坑点罗列,以起到回顾反思之效。
由于之前已经刷了一些题,这次就先从昨晚刚做的题开始。

题意回顾:

输入规格:给出 N1 N2 tag radix,N1和N2均不多余10个数字,每个数字取值范围是{0-9,a-z},a-z分别代表10-35。若tag=1,则radix代表N1的进制;若tag=2,则radix代表N2的进制。
输出规格:若能寻一进制,使得N1==N2,则输出此进制;否则输出"Impossible"。若解不唯一,则输出解集中最小的进制。

思路:

此处假设tag==1。若N2只有一位数,比较N1的十进制和N2的大小,若相等,则要求寻找的进制有多解,最小解为N2+1;否则只有唯一解或无解,将N1、N2均转换成十进制进行比较大小,对要求寻找的进制采用二分法查找(时间复杂度为log(N))。

个人坑点解析:

1.要求寻找的那个进制不局限于2-36,所以二分法查找时右侧需设的很大,这里采用long long类型;
2.long long类型的数据上限为2^63-1,在赋值给右边时,我尝试采用pow(2,63),结果溢出了,后采用0x7FFFFFFFFFFFFFFF,结果正确;
3.二分法查找时,mid=(left+right)/2,注意left+right可能产生溢出现象,此处谨慎起见可以使right=0x7FFFFFFFFFFFFFFF-left;
4.mid /=2时,个人建议使用位运算,即mid>>=2,算法效率将会比算术运算快很多很多,否则有可能产生超时(第七个测试点);
5.在给left赋初值时不能从2开始!从你要求进制的那个数的最大dight数+1开始!否则测试点19会错误。

代码:

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int number(char c)//计算一个digit的数字大小
{
 if (c - '0' >= 0 && c - '0' <= 9)
 	 return c - '0';
 else
 	 return c - 'a' + 10;
}
long double compute(char c[], long long radix)//计算一个radix进制数的十进制大小
{				
 int len = strlen(c);
 long double total = 0;
 for (int i = 0; i < len; i++)
 	 total += number(c[i])*pow(radix, len - i - 1);
 return total;
}
long long Radix(char c1[], char c2[], int radix)//数c1的进制为radix,计算c2的进制,若找不到一个进制使得c1==c2,返回-1
{
 int c2_len = strlen(c2);
 if (c2_len == 1)//思路的分号前一句话的情况
 {
  if (compute(c1, radix) == number(c2[0]))
 	  return number(c2[0]) + 1;
  else
 	  return -1;
 }
 long double c1_num = compute(c1, radix);//以下是思路中所说的第二种情况,c1_num为c1十进制大小
 int max=0;
 for (int i = 0; i < c2_len; i++)
 	 if (number(c2[i]) > max)
   		max = number(c2[i]);
 long long left = max + 1, right = 0x7FFFFFFFFFFFFFFF - left, mid;//right赋此值防止mid溢出
 long double c2_num;//c2_num同
 while (left <= right)//二分法
 {
  mid = left + right;
  mid >>= 1;    //位运算效率奇高,尤其这么多次循环和这么大数字,“/=2”就太慢了
  c2_num = compute(c2, mid);
  if (c2_num > c1_num)
  	 right = mid - 1;
  else if (c2_num < c1_num)
   	left = mid + 1;
  else
  	 return mid;
 }
 return -1;
}
int main()
{
 char N1[12], N2[12];
 int tag, radix;
 cin >> N1 >> N2 >> tag >> radix;
 long long red;
 if (tag == 1)
 	 red = Radix(N1, N2, radix);
 else
	  red = Radix(N2, N1, radix);
 if (red == -1)
	  cout << "Impossible";
 else
 	 cout << red;
 return 0;
}

以上是个人的解题思路,作者还是个大二萌新,不足之处还望有缘路过的大佬们批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值