1 条题解
-
0
思路与算法
按从小到大枚举候选进制B=2至40。每个输入文本先检查每个数码d是否小于B,否则该进制不合法。合法时用v=v*B+d把数码依次折算为整数。
为避免直接计算p值乘q值可能超过有符号64位上界,使用等价条件:r值能被q值整除,且r值/q值等于p值。所有输入为正整数,合法数码下q值也为正,除法安全。找到第一个满足者就输出B;遍历全部候选仍未找到则输出0。
正确性说明
按位权定义,Horner式v=vB+d在读完每个前缀时恰为该前缀表示的数值,因此转换准确。任何不小于B的数码都不能出现在B进制数中,先排除它是必要且正确的。对合法正整数a、b、c,c%b=0且c/b=a当且仅当ab=c,所以无需乘法也能准确验证题目等式。进制升序枚举覆盖全部2至40,首次满足的必为最小进制;若均不满足,按要求输出0。
复杂度
令L为三个输入数码总长。每个进制转换O(L),候选仅39个,总时间O(39L),保存输入需O(L),其余额外空间O(1)。初始化三个字符串和候选变量的开销包含在读入中。
原十进制输入不超过1000000,去掉前导零后最多7位,7位时只能为1000000。因此任意候选进制下的单个值不超过40^6=4096000000,long long可保存;但其平方40^12=16777216000000000000超过有符号64位上界。参考程序使用除法判等,避免这个真实边界问题。
易错点
数码必须严格小于进制,不能只检查p和q而忽略r。输入字符只有0至9,即使B大于10也不引入A至Z数码。多个进制可行时取最小;本批有最小2、3、10、13、39、40及无解0。输入1000000的乘法边界不能用有符号long long直接乘两边,代码已避免。
参考代码(C++11)
#include <iostream> #include <string> using namespace std; long long value(const string &s, int base) { long long v = 0; for (char c : s) { int d = c - '0'; if (d >= base) return -1; v = v * base + d; } return v; } int main() { string p, q, r; cin >> p >> q >> r; for (int base = 2; base <= 40; ++base) { long long a = value(p, base), b = value(q, base), c = value(r, base); if (a < 0 || b <= 0 || c < 0) continue; if (c % b == 0 && c / b == a) { cout << base << '\n'; return 0; } } cout << 0 << '\n'; }
- 1