24点游戏大家都应该玩过吧,就是有四张牌,四张牌都是1到10的正整数,要求你只能使用+ - * / ()使最终的表达式的结果为24
比如四张牌是 1 3 6 9,那么24=(6-3)*(9-1).如果这四个数可以算出24,就输出样例的表达式,如果不能,就输出no
思路:这个题是个典型的dfs,总共的可能有4*4*4*4!=1536种,这里的符号每次需要更新,在最后需要判断()的地方,分几种情况,首先我们假设+ -为A,* /为B,那么最终的结果有AAA BBB ABA BAB AAB BBA ABB BAA 8种情况,ABB需要变为(A)BB,AAB需要变为(AA)B,BAB需要变为(BA)B,其他情况就不用特别处理。有很多人会问会不会出现这种情况,比如说2 10 7 3,会不会输出的结果是24=(2+10*7)/3,这种情况是不会出现的,结果的输出会是24=2*10-3+7,因为我们处理的时候是按照数列从小到大处理的。(即全排列从小到大,比如说123的全排列从小大到就是123 132 213 231 312 321)
附上代码:
#include <bits/stdc++.h>
using namespace std;
int check=0;
char ah,bh,ch,symbel;
void dfs(int index,int result,int arr[])
{
switch(index)
{
case 2:ah=symbel;break;//第一个运算符
case 3:bh=symbel;break;//第二个运算符
case 4:ch=symbel;break;//第三个运算符
}
if(result==24&&index==4){//找到了就更换标记
check=1;
return;
}
if(index>=4||check)//如果没找到或者找到了都退出
return;
for(int i=0;i<4;i++){
if(i==0){
symbel='+';
dfs(index+1,result+arr[index],arr);
}
else if(i==1){
symbel='-';
dfs(index+1,result-arr[index],arr);
}
else if(i==2){
symbel='*';
dfs(index+1,result*arr[index],arr);
}
else if(result%arr[index]==0){
symbel='/';
dfs(index+1,result/arr[index],arr);
}
if(check)
break;
}
}
int main()
{
int num[4],n=100;
while(n--){
check=0;
printf("请输入四个大于0小于10的整数\n");
for(int i=0;i<4;i++) cin>>num[i];
sort(num,num+4);
while(next_permutation(num,num+4)){//调用函数,数列进行全排列
dfs(1,num[0],num);
if(check) break;
}
if(check){//符号的特别处理
if(ah!='*'&&ah!='/'){
if(bh=='*'||bh=='/') printf("24=(%d%c%d)%c%d%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
else if(ch=='*'||ch=='/') printf("24=(%d%c%d%c%d)%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
else printf("24=%d%c%d%c%d%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
}
else if(bh!='*'&&bh!='/'){
if(ch=='*'||ch=='/') printf("24=(%d%c%d%c%d)%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
else printf("24=%d%c%d%c%d%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
}
else printf("24=%d%c%d%c%d%c%d\n",num[0],ah,num[1],bh,num[2],ch,num[3]);
}
else cout<<"no"<<endl;
}
return 0;
}