卡普列加数是指正整数n满足其平方n²的十进制字符串可被分割为左右两部分(右长∈[1,len−1],右非全零),左部(空则为0)与右部数值之和等于n;判断时需遍历所有合法分割位置,用string转数值并特判n=1及左空、右全零情况。

什么是卡普列加数,判断逻辑怎么写
一个正整数 n 是卡普列加数(Kaprekar number),当且仅当它的平方 n * n 能被拆成两部分(左、右),这两部分相加恰好等于 n,且右半部分必须非零(即不能全为前导零),左半部分允许为空(即相当于 0)。
例如:9 是卡普列加数,因为 9*9 = 81,拆成 "8" 和 "1",8 + 1 == 9;45 也是,因为 45*45 = 2025,拆成 "20" 和 "25",20 + 25 == 45。
关键点不是“任意拆”,而是按平方结果的**十进制位数**来切:对 n² 的字符串表示,尝试所有可能的分割位置(从最右边起至少留 1 位给右半部分),即右半部分长度 ∈ [1, len(n*n)−1],其余为左半部分(可为空字符串,对应数值 0)。
用 std::to_string 和 stoll 实现安全拆分
直接操作字符串比手动取模更直观、不易错,尤其避免了 10^k 溢出或除零问题。但要注意几个边界:
-
n == 1是合法卡普列加数(1*1 == "1"→ 左=""(=0),右="1" → 0+1==1) - 右半部分不能是全 '0' 字符串(如
n=10,100拆成 "10"+"0" 不合法,因为右="0" → 数值为 0,违反“右半部分非零”规则) - 左半部分为空字符串时,
stoll("")会抛异常,必须显式处理
实操建议:
pow(10, rlen)
-
pow(10, rlen)返回double,转long long时精度丢失(如pow(10,15)可能变成 999999999999999) - 整数除法对
n=1或n=10等边界值行为不直观(比如100 / 100 == 1,但你想拆成 "1"+"00",而 "00" 不合法) - 无法自然跳过右半部分为全零的情况(需额外检查
sq % base == 0)
字符串方式虽略慢,但逻辑清晰、无精度陷阱、边界可控——对单次判断而言性能差异可忽略。
注意 long long 的上限和输入范围
卡普列加数本身增长稀疏,但 n² 很快溢出。例如:10^9 的平方是 10^18,刚好在 long long(通常 64 位)范围内;10^10 就溢出了。
若需支持更大 n,必须用高精度库(如 boost::multiprecision)或字符串模拟乘法。但绝大多数实际场景(如 OJ 题、教学示例)中,限定 n ≤ 10^9 即可,此时 long long 安全。
另外,std::stoll 对超长字符串会抛异常,所以务必确保 rlen 且 left 和 right 长度合理——上面循环已保证这点。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











