题目说明
为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要经常性地进行体力训练和智力训练!某批警察叔叔正在进行智力训练:
1 2 3 4 5 6 7 8 9 = 110;
请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格的填法;123+4+5+67-89 是另一个可能的答案。
请你利用计算机的优势,帮助警察叔叔快速找到所有答案。
每个答案占一行。形如:
12+34+56+7-8+9
123+4+5+67-89
程序清单
#include <stdio.h>
// 递归方式构造表达式
int constructExpression(int n, int src[],int exp[], int target)
{
int i,j; // 用于循环中使用的循环变量
int sign[3] = {0, -1, -2}; // 0代表没有符号,-1代表加号,-2代表减号
exp[2*n-2] = src[n-1];
if(n==9){ // 测试到第几个数字,9表示最后一个数字,递归出口
if(getResult(exp, target)){
printExpression(exp, target);
}
return 0;
}else{
for(i=0;i<3;i++){ // 填充符号,递归构造表达式
if(sign[i]==0){ // 填充符号
exp[2*n-1] = 0;
}else if(sign[i]== -1){
exp[2*n-1] = -1;
}else if(sign[i]== -2){
exp[2*n-1] = -2;
}
constructExpression(n+1, src, exp, target); // 递归构造后部表达式
}
}
return 0;
}
// 计算表达式结果
int getResult(int exp[], int target){
int i;
int index = 0; // 新数组的索引
int newexp[17];
int result = 0;
// 将表达式转换成标准算式
for(i=0;i<17;i++){
if(exp[i] != 0){
newexp[index] = exp[i];
index ++;
}else{
index --; // 当遇到0时,说明前后数字应该组合后存入,而不是只存0前面的数
newexp[index] = newexp[index] * 10 + exp[i+1]; // 0左面的数 * 10+0右面的数
i++; // 跳过0右面的数
index ++;
}
}
// 计算表达式结果
result = newexp[0];
for(i=1;i<=index/2;i++){
if(newexp[2*i-1] == -1){
result += newexp[2*i];
}else {
result -= newexp[2*i];
}
}
// 判断是否是所需的表达式
if(result == target){
return 1;
} else{
return 0;
}
}
// 打印结果输出表达式
int printExpression(int exp[],int target){
int i;
for(i=0;i<17;i++){
if(exp[i] == 0){
continue;
}else if(exp[i] == -1){
printf(" %c ", '+');
}else if(exp[i] == -2){
printf(" %c ", '-');
}else{
printf("%d", exp[i]);
}
}
printf(" = %d\n", target);
return 0;
}
int main(){
int src[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int exp[17];
constructExpression(1, src, exp, 110);
return 0;
}
运行结果