PAT-A1010解题报告
第一遍做这道题时就有了很朴素的想法,先把已知进制的数转换成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的进制,找到一个使等式成立的最小进制。
注意点
- 题目中并没有指明已知进制数 N 1 N_1 N1的范围,但是经过测试,使用
long long
能够存下转换为10进制后的 N 1 N_1 N1。 - 在我们二分处理 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。 - 给定 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解题报告相关推荐
- 卡拉兹猜想java,pat乙级1001解题报告
卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...
- uscao 线段树成段更新操作及Lazy思想(POJ3468解题报告)
线段树成段更新操作及Lazy思想(POJ3468解题报告) 标签: treequerybuildn2cstruct 2011-11-03 20:37 5756人阅读 评论(0) 收藏 举报 分类: ...
- 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- 【解题报告系列】超高质量题单 + 题解(ACM / OI)超高质量题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我新写的超高质量的题解和代码,题目难度不 ...
- 解题报告(三)多项式求值与插值(拉格朗日插值)(ACM / OI)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- 解题报告(十三)中国剩余定理(ACM / OI)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- 解题报告(四)生成函数(ACM/ OI)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解
繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...
- 解题报告(一)E、(BZOJ4589)Hard Nim(博弈论 + FWT)
繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...
- 解题报告(五)组合计数(ACM / OI)超高质量题解
繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...
最新文章
- 一些我们码代码过程中有用的小技巧
- easymock 图片_easy-mock的使用
- Servlet+Tomcat制作出第一个运行在Tomcat上的Java应用程序
- 基于注解的Spring AOP的配置和使用--转载
- 【Qt】水平和垂直布局
- 阿里云 centos ssh key 客户端 无密码登录 ssh 登录
- tensorflow之tf.train.exponential_decay()指数衰减法
- Vue中message.split().reverse().join()函数用法
- 【定有惊喜】android程序员如何做自己的API接口?php与android的良好交互(附环境搭建),让前端数据动起来~...
- CI中创建你自己的类库
- awk substr()函数
- css3中的@font-face的用法(定义多个规则)
- git clone出错
- 账龄分析表excel模板_智能考勤表excel表模板
- 网页截图小技巧——利用浏览器自带功能即可(无需安装插件)
- Inside Real-Time Linux
- Log Parser Lizard(日志分析工具)v6.7.1官方版
- IDEA中suppress warnings
- VisualStudio 编译出来的程序不兼容Win7
- java 类型参数推断