![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
问题描述 计算器和计算机的大量普及也有其弊端。即便是受过专业技术训练的学生们也很可能缺乏计算能力。由于电脑的大量使用,很多人无法心算出7*8这样的算式,甚至是用纸和笔也算不出13*17。不过谁在意呢? Bartjens教授十分在意——因为他比较传统。他决定给学生布置一些计算作业,并且不能使用电子设备。为了批改方便,他决定使得几乎所有题答案都是2000,不过不全是,否则会被学生发现然后就不仔细计算了。 不幸的是,Bartjens教授的打印机实在是太旧了,不能和新的打印机兼容。打印出了题目后,教授发现所有的符号都丢失了!例如2100-100=,被打印成了2100100=。不过,数字和等号被正确的打印了。 更糟糕的是,教授的试题原稿不见了。因此,他需要恢复出这些题原来的样子。如果答案是2000,那么2100100=可能是: 2100-100= 2*100*10+0= 2*100*10-0= 2*10*0100= 2*-100*-10+0= Bartjen教授记得几点: 1.他写的数字没有前导零。例如2*10*0100=就是不可行的。 2.他写0的时候不会写多个0。例如2*1000+000=就是不可行的。 3.他只用二元运算符,不用取负。所以2*-100*-10+0=也不合法。 4.他只用+、-、*,不用/和括号。 5.这些算式按照正常的优先级顺序计算。 你需要帮助barjen教授恢复这些题目。你需要在算式中插入至少一个运算符,使得答案是2000。有多少种可能的算式呢? 输入格式 输入包含一组数据。这组数据有n个数字(1<=n<=9),后面跟着一个=号。 输出格式 输出包含若干行,每一行是一个可行的解,具体格式见样例。按字典序从小到大输出这些字符串。如果无解,输出一行IMPOSSIBLE。 样例输入 2100100= 【样例输出】 2*100*10+0= 2*100*10-0= 2100-100= 数据规模和约定 1<=n<=9
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define USE_LEN 10 5 #define OPERATE_LEN 4 6 #define RES 2000 7 8 int flag = 0; 9 10 void judge(int index,const char *arr,const char *ch) 11 { 12 int i,j,tmp,sum,res; 13 int tmp_num[USE_LEN]; //存储组合的数字 14 char tmp_ch[USE_LEN]; 15 16 //1.验证是否符合要求 17 tmp=sum=0; 18 for (i=0 ; i<index ; i++) //遍历输入的数字 19 { 20 //组合数字 21 if (sum == 0) 22 { 23 sum = arr[i]-'0'; 24 } 25 else 26 { 27 sum = sum*10+(arr[i]-'0'); 28 } 29 30 if (ch[i]!=' ') 31 { 32 tmp_num[tmp] = sum; 33 tmp_ch[tmp] = ch[i]; 34 sum = 0; 35 tmp ++; 36 } 37 else 38 { 39 if (sum==0 && i!=index-1) 40 return ;//0***的数字不符合要求 41 } 42 } 43 44 45 //2.验证是否满足要求 46 res = tmp_num[0]; 47 i=0,j=1; //i标记运算符下标 , j标记数字 48 while (j < tmp) 49 { 50 if (tmp_ch[j] =='*') 51 { 52 sum = tmp_num[j]; 53 while (tmp_ch[j] == '*') 54 { 55 sum *= tmp_num[++j]; 56 } 57 } 58 else 59 { 60 sum = tmp_num[j]; 61 } 62 63 switch(tmp_ch[i]) 64 { 65 case '+':res +=sum;break; 66 case '-':res -=sum;break; 67 case '*':res *=sum;break; 68 } 69 i = j++; 70 } 71 72 73 //3.打印符合要求的式子 74 if (res == RES) 75 { 76 flag ++; 77 for (i=0 ; i<index ; i++) 78 { 79 printf("%c",arr[i]); 80 if (ch[i]!=' ' && ch[i]!=0) 81 printf("%c",ch[i]); 82 } 83 printf("=\n"); 84 } 85 return ; 86 } 87 88 void dfs(int index,int len,const char *arr,char *ch) 89 { 90 int i; 91 char operate[OPERATE_LEN] = {'*','+','-',' ',}; //可用运算符 92 if (len == 1)//运算符插入完成 (符号数比数字少1) 93 { 94 judge(index+1,arr,ch); //判断插入运算符后的式子是否符合要求 95 return ; 96 } 97 else 98 { 99 for (i=0 ; i<OPERATE_LEN ; i++) 100 { 101 ch[index] = operate[i];//插入运算符 102 dfs(index+1,len-1,arr,ch); 103 } 104 } 105 106 return ; 107 } 108 109 int main(void) 110 { 111 char arr[USE_LEN]; //存储输入数据 112 char ch[USE_LEN]; //存储插入的符号 (放在每个数字后面) 113 114 memset(arr,0,sizeof(arr)); 115 memset(ch,0,sizeof(ch)); 116 117 scanf("%s",arr); 118 if (strcmp(arr,"2000=") == 0) //至少插入一个运算符 119 { 120 printf("IMPOSSIBLE"); 121 return 0; 122 } 123 else 124 { 125 dfs(0,strlen(arr)-1,arr,ch); //枚举情况 126 } 127 128 if (flag == 0) 129 printf("IMPOSSIBLE"); 130 131 return 0; 132 }
解题思路:
将运算符“*”,“+”,“-”,“ ”插入到数字中,
枚举其不同组合情况下符合条件的。
采用DFS搜索满足条件的组合