如何用C语言编写程序验证1-13位数字的数位分割平方和特性?
数位分割组合和的平方等于原数的C语言实现方案
原代码的问题分析
你提供的代码存在两处致命问题:
- 语法错误:
while循环缺少闭合的},导致return语句被包含在循环内部,程序逻辑完全混乱。 - 逻辑错误:代码固定按「1位+2位」的交替方式分割数位,无法覆盖所有可能的分割组合(比如示例中1296的
1+29+6分割方式,原代码根本无法处理)。
正确实现思路
要解决这个问题,核心是枚举所有可能的数位分割方式,同时可以通过以下优化减少计算量:
- 先判断输入数字是否为完全平方数:若原数
num不是某个整数s的平方,则直接排除,无需遍历分割组合。 - 若
num是完全平方数,将其转换为字符串,通过递归/回溯的方式枚举所有分割点,计算分割后的数字之和是否等于s,同时记录合法的分割路径。
完整代码实现
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> // 递归函数:尝试分割字符串,判断是否能得到和为target的组合 int splitAndCheck(const char *numStr, int pos, unsigned long long currentSum, unsigned long long target, char *result) { // 处理到字符串末尾,检查当前和是否等于目标值 if (pos == strlen(numStr)) { return currentSum == target; } unsigned long long num = 0; char temp[14]; // 存储当前分割的数字字符串 int tempIdx = 0; for (int i = pos; i < strlen(numStr); i++) { // 处理前导零:如果当前分割的数字长度大于1且以0开头,跳过 if (i > pos && numStr[pos] == '0') { break; } num = num * 10 + (numStr[i] - '0'); // 防止溢出:如果当前数字已经超过目标和,无需继续分割更长的数位 if (num > target) { break; } // 记录当前分割的数字到temp temp[tempIdx++] = numStr[i]; temp[tempIdx] = '\0'; // 保存当前result的长度,用于回溯 int prevLen = strlen(result); if (prevLen > 0) { strcat(result, "+"); } strcat(result, temp); // 递归处理下一个位置 if (splitAndCheck(numStr, i + 1, currentSum + num, target, result)) { return 1; // 找到合法组合,返回true } // 回溯:恢复result到之前的状态 result[prevLen] = '\0'; tempIdx--; } return 0; // 所有分割方式都不合法,返回false } int main() { char input[14]; printf("请输入1-13位数字:"); scanf("%s", input); // 转换为数值 unsigned long long num = strtoull(input, NULL, 10); // 计算平方根,判断是否为完全平方数 unsigned long long s = sqrt(num); if (s * s != num) { printf("%llu 不存在符合条件的分割组合\n", num); return 0; } char result[100] = ""; if (splitAndCheck(input, 0, 0, s, result)) { printf("%llu = (%s) = %llu²\n", num, result, s); } else { printf("%llu 不存在符合条件的分割组合\n", num); } return 0; }
代码说明
- 完全平方数判断:先通过
sqrt计算平方根s,验证s*s是否等于原数,快速排除非目标数。 - 递归分割逻辑:
- 从字符串的起始位置开始,尝试分割出1位、2位...直到末尾的数字。
- 跳过带有前导零的多位数(如
029),但允许单个0(如示例中的998001分割出0+0)。 - 若当前分割的数字超过目标和
s,直接停止该分支的分割,避免无效计算。
- 回溯记录分割路径:在递归过程中记录合法的分割组合,找到符合条件的组合后立即返回,输出结果。
测试示例
输入1296,程序输出:
1296 = (1+29+6) = 36²
输入3025,程序输出:
3025 = (30+25) = 55²
内容的提问来源于stack exchange,提问作者jojo nirvana
相关产品推荐
相关产品推荐

