【1010 25 二分】 Radix

传送门

题意

给定 \(N_{1},N_{2}\)\(tag\)\(radix\),其中 \(tag=1\) 表示 \(radix\) 表示的是 \(N_{1}\) 的进制,否则为 \(N_{2}\) 的进制,求出另一个数的进制使得两个数字值相等,如果没有这样的进制输出 \(impossible\)

数据范围

\(digit\in \{ 0\sim 9\}| \{a\sim z\}\)

题解

  • max_element/min_elemeny(begin, end, cmp),返回的是迭代器,取值需要用 *,减去首地址后即从 0 开始的对应下标
  • 根据 \(tag\) 如果表示的是 \(N_{2}\) 的进制,则交换一下,方便处理
  • 进制不一定等于 digit 上的最大值,没有限定
  • 二分下界一定 \(\geq N_1 + 1\) 的最大值,+1 是因为数字取不到进制数,因为有 impossible,直接给下界会出错
  • 二分的上界可以定位下界和待匹配数字的最大值,因为可能 long long 溢出,通过 <0 可以判断

Code

#include <bits/stdc++.h>
using namespace std;

#define ll long long

unordered_map<char, int> ump;

ll cal(string x, ll radix) {
	ll res = 0;
	for (auto it : x) {
		res = res * radix + ump[it];
	}
	return res;
}

int main() {
	string n1, n2; cin >> n1 >> n2;
	ll tag, radix1; cin >> tag >> radix1;
	if (tag == 2) swap(n1, n2);

	for (int i = 0 ; i < 36; i++) ump.insert({i < 10 ? i + '0' : i - 10 + 'a', i});

	ll N1 = cal(n1, radix1);
	
	char mx = *max_element(n2.begin(), n2.end(), 
		[](char c1, char c2) { return c1 < c2;});

	ll l = ump[mx] + 1, r = max(1ll * 35, N1) + 1;
	while (l < r) {
		ll mid = (l + r) / 2;
		ll res = cal(n2, mid);
		if(res >= N1 || res < 0) r = mid;
		else l = mid + 1;
	} 
	if (cal(n2, l) == N1) cout << l;
	else cout << "Impossible";
}
posted @ 2021-01-26 14:13  Hyx'  阅读(61)  评论(0)    收藏  举报