思路
坑点:如果不注意到另一个进制可能很大,不止36,就可能不会考虑到二分。
使用二分算法注意:
- 二分的左右边界
左边界是未知进制的串中最大的数字+1
右边界是十进制表示的已知进制数+1(此时在该进制下可用1位表示) - 题目要求:如果答案不唯一,则输出更小的进制数
即求第一个使结果大于等于target的值
爆int注意
C++ 代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int get(int c) {
if (c >= '0' && c <= '9') return c - '0';
return c - 'a' + 10;
}
LL calc(string n1, LL radix) { //秦九韶算法
LL res = 0;
for (auto c : n1) {
if ((double)res * radix + get(c) > 1e16) return 1e18;//判断是否溢出
res = res * radix + get(c);
}
return res;
}
int main() {
string n1, n2;
cin >> n1 >> n2;
int tag, radix;
cin >> tag >> radix;
if (tag == 2) swap(n1, n2);
LL target = calc(n1, radix);
// cout << target << "\n";
LL l = 0, r = target + 1;
for (auto c : n2) l = max(l, (LL)get(c) + 1);
while (l < r) { //第一个大于等于
LL mid = l + r >> 1;
if (calc(n2,mid) >= target) r = mid;
else l = mid + 1;
}
// cout << l << ' ' << calc(n2, l) << "\n";
if (calc(n2, l) != target) cout << "Impossible";
else cout << l << "\n";
return 0;
}
请问一下为什么左边界不能是0呢
十进制的数中只能出现1~9,如果你已经知道串中最大的数是9,那么他至少是10进制
这个我明白,可是二分左边界一定要从最大数+1吗,从0开始不行吗hh,二分不是每次找一半吗,这样不行吗hhh(不要嘲笑我,我是小白hh)
假如给你9 9 1 10这组样例,左边界是0,按照位置数字系统计算,0进制的9(假设存在)转化成10进制表示,仍是9。那最后的答案就是0进制的9等于10进制下的9,实际上这没有意义。
get函数里面应该形参应该不是int类型吧。。
char类型本质就是数字,和int运算时会隐式转换为int