第一遍做这道题时就有了很朴素的想法,先把已知进制的数转换成10进制,再对未知进制进行二分。但是提交后发现很多测试点没有通过,仔细看了《算法笔记》后才发现有很多细节没有把握好,在这里就记录下我的解题过程,为后来者填坑。


思路

题目要求找一个未知进制,满足 N 1 = N 2 N_1=N_2 N1​=N2​,只需把二者都转换成10进制进行比较。假设 N 2 N_2 N2​的进制未知,能够很容易地推出, N 2 N_2 N2​的大小随着进制的增加而增加,这样我们就能二分处理 N 2 N_2 N2​的进制,找到一个使等式成立的最小进制。


注意点

  1. 题目中并没有指明已知进制数 N 1 N_1 N1​的范围,但是经过测试,使用long long能够存下转换为10进制后的 N 1 N_1 N1​。
  2. 在我们二分处理 N 2 N_2 N2​的进制时,我们需要指定二分范围, N 2 N_2 N2​可能的二分下界是 N 2 N_2 N2​的所有位中的最大数加1;二分上界的确定存在坑,不要认为数字的每一位都是0~9, a~z中的数就认为上界是36,实际上上界是 m a x ( l o w , N 1 ) max(low, N_1) max(low,N1​)(其中low为二分下界)。

    如果取上界为 N 1 N_1 N1​,当 N 1 , N 2 N_1, N_2 N1​,N2​都为0时, l o w = 1 low=1 low=1,很显然二分上界应当是1,而不应该是0。
    为什么不取上界为 m a x ( l o w , N 1 − 1 ) max(low, N_1-1) max(low,N1​−1)?假设 N 2 N_2 N2​只有第二位的数为 1 1 1,其它位都为0,如果取最大进制为 N 1 − 1 N_1-1 N1​−1, N 2 N2 N2就等于 N 1 − 1 N_1-1 N1​−1,取最大进制为 N 1 N_1 N1​,则 N 2 N_2 N2​恰好等于 N 1 N_1 N1​。
    为什么不取上界为 m a x ( l o w , N 1 ) + 1 max(low, N_1)+1 max(low,N1​)+1?当 N 2 N_2 N2​除了最后一位外存在非0的位,则 N 2 > N 1 N_2>N_1 N2​>N1​,如果 N 2 N_2 N2​只有最后一位非0,会出现 N 2 = N 1 N_2=N_1 N2​=N1​的情况只有 N 2 N_2 N2​的最后一位为 N 1 N_1 N1​,这时 l o w low low就为 N 1 + 1 N_1+1 N1​+1, N 2 N_2 N2​只要进制为 m a x ( l o w , N 1 ) max(low, N_1) max(low,N1​)就会等于 N 1 N_1 N1​,因为我们要取所有满足条件的进制中的最小进制,故我们用不着讨论进制 m a x ( l o w , N 1 ) + 1 max(low, N_1)+1 max(low,N1​)+1。

  3. 给定 N 2 N_2 N2​的进制,计算其对应的10进制并与 N 1 N_1 N1​进行比较时,需要考虑 N 2 N_2 N2​在转换为10进制时出现溢出的情况,如果出现溢出, N 2 N_2 N2​一定大于 N 1 N_1 N1​。

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cctype>
#include <cstring>
#include <algorithm>typedef long long LL;
#define INF 1 << 30
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
LL LLINF = ~(1LL << 63);using namespace std;void Swap(int &a, int &b)
{int temp = a;a = b;b = temp;
}
LL ToDecimal(char str[], LL radix, LL up_bound)//把一个数按照指定进制转换为10进制数
{int len = strlen(str);LL ans = 0;for (int i = 0; i < len; i++){if (isdigit(str[i])){ans = ans * radix + (LL)(str[i] - '0');}else{ans = ans * radix + (LL)(str[i] - 'a' + 10);}if (ans < 0 || ans > up_bound) return -1;}return ans;
}
int LeastRadix(char str[])//计算二分下界
{int len = strlen(str);int ans = 0;for (int i = 0; i < len; i++){if (isdigit(str[i])) ans = MAX(ans, str[i] - '0' + 1);else ans = MAX(ans, str[i] - 'a' + 11);}return ans;
}
int cmp(LL num_deci, char num_wait[], LL radix)//比较N1和N2
{LL num_trans = ToDecimal(num_wait, radix, num_deci);if (num_trans < 0) return -1;//溢出,num_wait一定大if (num_deci < num_trans) return -1;if (num_deci == num_trans) return 0;return 1;
}
int GetRadix(LL num_deci, char num_wait[], LL left, LL right)
{LL mid;LL ans = LLINF;while (left <= right){mid = (left + right) / 2;int res = cmp(num_deci, num_wait, mid);if (res < 0){right = mid - 1;}else if (res == 0){ans = MIN(ans, mid);right = mid - 1;}else{left = mid + 1;}}if (ans != LLINF) return ans;else return 0;
}
int main()
{int tag, ans;LL radix;char N1[15], N2[15], temp[15];scanf("%s%s%d%lld", N1, N2, &tag, &radix);if (tag == 2){strcpy(temp, N1);strcpy(N1, N2);strcpy(N2, temp);}LL num1 = ToDecimal(N1, radix, LLINF);LL least = LeastRadix(N2);LL largest = MAX(least, num1) + 1;if (ans = GetRadix(num1, N2, least, largest)){printf("%d\n", ans);   }else printf("Impossible\n");return 0;
}

PAT-A1010解题报告相关推荐

  1. 卡拉兹猜想java,pat乙级1001解题报告

    卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...

  2. uscao 线段树成段更新操作及Lazy思想(POJ3468解题报告)

    线段树成段更新操作及Lazy思想(POJ3468解题报告) 标签: treequerybuildn2cstruct 2011-11-03 20:37 5756人阅读 评论(0) 收藏 举报  分类: ...

  3. 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  4. 【解题报告系列】超高质量题单 + 题解(ACM / OI)超高质量题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我新写的超高质量的题解和代码,题目难度不 ...

  5. 解题报告(三)多项式求值与插值(拉格朗日插值)(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  6. 解题报告(十三)中国剩余定理(ACM / OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  7. 解题报告(四)生成函数(ACM/ OI)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...

  8. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  9. 解题报告(一)E、(BZOJ4589)Hard Nim(博弈论 + FWT)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  10. 解题报告(五)组合计数(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

最新文章

  1. 一些我们码代码过程中有用的小技巧
  2. easymock 图片_easy-mock的使用
  3. Servlet+Tomcat制作出第一个运行在Tomcat上的Java应用程序
  4. 基于注解的Spring AOP的配置和使用--转载
  5. 【Qt】水平和垂直布局
  6. 阿里云 centos ssh key 客户端 无密码登录 ssh 登录
  7. tensorflow之tf.train.exponential_decay()指数衰减法
  8. Vue中message.split().reverse().join()函数用法
  9. 【定有惊喜】android程序员如何做自己的API接口?php与android的良好交互(附环境搭建),让前端数据动起来~...
  10. CI中创建你自己的类库
  11. awk substr()函数
  12. css3中的@font-face的用法(定义多个规则)
  13. git clone出错
  14. 账龄分析表excel模板_智能考勤表excel表模板
  15. 网页截图小技巧——利用浏览器自带功能即可(无需安装插件)
  16. Inside Real-Time Linux
  17. Log Parser Lizard(日志分析工具)v6.7.1官方版
  18. IDEA中suppress warnings
  19. VisualStudio 编译出来的程序不兼容Win7
  20. java 类型参数推断

热门文章

  1. 程序员需要晓得是术语
  2. 35岁到40岁,如何突破
  3. 字符串转化为Json
  4. Simulink三相异步电机仿真
  5. matlab 绘制高斯(Gaussan)函数图像
  6. 监督学习(supervised learning)与非监督学习(unsupervised learning)
  7. mac php fpm 启动,mac 启动php-fpm
  8. (18)ROS学习-TF坐标变换之静态坐标变换
  9. MVC详解:mvc是什么?为什么要用MVC?MVC工作原理以及MVC优缺点
  10. 微信支付APP支付完全攻略