1 条题解

  • 0
    @ 2026-10-26 10:54:56

    思路与算法

    按从小到大枚举候选进制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

    信息

    ID
    1707
    时间
    1000ms
    内存
    64MiB
    难度
    进阶
    标签
    递交数
    1
    已通过
    1
    上传者