一副扑克牌的每张牌表示一个数(J、Q、K分别表示11、12、13,两个司令都表示6)。任取4张牌,即得到4个1~13的数,请添加运算符(规定为加+ 减- 乘* 除/ 四种)使之成为一个运算式。每个数只能参与一次运算,4个数顺序可以任意组合,4个运算符任意取3个且可以重复取。运算遵从一定优先级别,可加括号控制,最终使运算结果为24。请输出一种解决方案的表达式,用括号表示运算优先。如果没有一种解决方案,则输出-1表示无解。
输入格式说明:
输入在一行中给出4个整数,每个整数取值在[1, 13]。
输出格式说明:
输出一种解决方案的表达式,用括号表示运算优先。如果没有解决方案,请输出-1。
样例输入与输出:
序号 | 输入 | 输出 |
1 | 2 3 12 12 | ((3-2)*12)+12 |
2 | 5 5 5 5 | (5*5)-(5/5) |
3 | 1 3 5 6 | (1+(3*6))+5 |
4 | 8 13 9 4 | 8+((13-9)*4) |
5 | 2 13 7 7 | 2*(13-(7/7)) |
6 | 5 5 5 2 | -1 |
用DFS来写,为了便于输出答案,添加一个string数组用于记录计算过程。注意double与0比较时不能用==
/*2015.8.5cyq*/
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
using namespace std;
const double threshold=1e-6;
bool dfs(vector<double> &data,vector<string> &str,int n){
if(n==1){
if(fabs(data[0]-24)<threshold)
return true;
else
return false;
}
//选择其中两张牌进行处理,数组长度减1进行dfs
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
double a=data[i];
double b=data[j];
data[j]=data[n-1];//第n张牌填入j的坑
string strA=str[i];
string strB=str[j];
str[j]=str[n-1];//第n张牌填入j的坑
//i所在的坑用来存储两张牌运算的结果
data[i]=a+b;
str[i]='('+strA+'+'+strB+')';
if(dfs(data,str,n-1))
return true;
data[i]=a-b;
str[i]='('+strA+'-'+strB+')';
if(dfs(data,str,n-1))
return true;
data[i]=a*b;
str[i]='('+strA+'*'+strB+')';
if(dfs(data,str,n-1))
return true;
if(fabs(b)>threshold){
data[i]=a/b;
str[i]='('+strA+'/'+strB+')';
if(dfs(data,str,n-1))
return true;
}
if(fabs(a)>threshold){
data[i]=b/a;
str[i]='('+strB+'/'+strA+')';
if(dfs(data,str,n-1))
return true;
}
//现场恢复
data[i]=a;
data[j]=b;
str[i]=strA;
str[j]=strB;
}
}
return false;
}
int main(){
vector<double> data(4);
vector<string> str(4);
for(int i=0;i<4;i++){
cin>>str[i];
if(str[i].size()==1)
data[i]=str[i][0]-'0';
else
data[i]=10+str[i][1]-'0';
}
int len=4;
if(dfs(data,str,len)){
string result=str[0];
str[0].erase(str[0].end()-1);//去掉最外层的括号
str[0].erase(str[0].begin());
cout<<str[0]<<endl;
}else
cout<<-1<<endl;
return 0;
}