1.输入输出约定
输入四个字符,分别代表四个扑克牌,约定:0字符为10,JQK分别为11 12 13.
输出运算过程,如果没有无解,输出 no ans.
2.运行截图
(1)有答案的
(2)无答案的
3.算法思路步骤
(1)输入四个字符,例如:2 6 J 0
(2)将字符转化为整数,其中0JQK分别转化为10 11 12 13
(3)使用深度优先算法,为4张牌排序
(4)对于每种排序方式,使用不同的运算符相连接,例如2 * 6 + 11- 10
(5)对于每种排序方式的每种运算符连接,分别考察两种计算方式
(6)第一种计算方式为瀑布式,例如:(((2*6)+11)-10)
(7)第二种计算方式为合并式,例如:(2*6)+(11-10)
(8)如果答案等于24,则输出运算过程
4.完整代码
#include<iostream>
#include<stack>
using namespace std;
bool isSort[4]; //牌是否使用
stack<int> mySort; //牌的次序
stack<int> copySort; //牌的次序的复制
int haveAns=0; //有多少个解法
int symbol[3]; //运算符号
int cardData[4]; //牌的数据
int ansSum=0; //游戏答案总数
/*
展示运算过程
type:1 滚雪球运算法,2 分别运算后再运算
*/
void showAns(int type){
haveAns++;
if(type==1){
cout<<"((( "<<cardData[0]<<" ";
for(int i=0;i<3;i++){
if(symbol[i]==0) cout<<"+"<<" ";
if(symbol[i]==1) cout<<"-"<<" ";
if(symbol[i]==2) cout<<"*"<<" ";
if(symbol[i]==3) cout<<"/"<<" ";
cout<<cardData[i+1]<<" ) ";
}
}
if(type==2){
cout<<"( "<<cardData[0]<<" ";
for(int i=0;i<3;i++){
if(symbol[i]==0) cout<<"+"<<" ";
if(symbol[i]==1) cout<<"-"<<" ";
if(symbol[i]==2) cout<<"*"<<" ";
if(symbol[i]==3) cout<<"/"<<" ";
if(i==0||i==2) cout<<cardData[i+1]<<" ) ";
if(i==1) cout<<"( "<<cardData[i+1]<<" ";
}
}
cout<<endl;
cout<<endl;
}
/*
计算过程
x:第一个数
t: 运算符 0+ 1- 2* 3/
y:第二个数
return:答案
*/
int calculate(int x,int t,int y){
if(x==-1||y==-1) return -1;
if(t==0) return x+y;
if(t==2) return x*y;
if(t==1){
if(x-y<0) return -1;
return x-y;
}
if(t==3){
if(y==0||x%y!=0) return -1;
return x/y;
}
}
/*
分支运算法
分别按照运算符算前两个数和后两个数,再将结果运算
*/
void checkMergeOK(){
int left,right;
left=calculate(cardData[0],symbol[0],cardData[1]);
right=calculate(cardData[2],symbol[2],cardData[3]);
left=calculate(left,symbol[1],right);
if(left==24) showAns(2);
}
/*
滚雪球运算法
以第一个数为起点,依次按对应运算符计算
*/
void checkSnowballOK(){
int ans=cardData[0];
for(int i=0;i<3;i++){
ans=calculate(ans,symbol[i],cardData[i+1]);
}
if(ans==24) showAns(1);
}
/*
遍历所有运算符情况
*/
void checkOK(){
for(int i=0;i<4*4*4;i++){
symbol[0]=i/16;
symbol[1]=(i/4)%4;
symbol[2]=i%4;
// cout<<symbol[0]<<" "<<symbol[1]<<" "<<symbol[2]<<endl;
copySort=mySort;
int iIndex=0;
while(!copySort.empty()){
cardData[iIndex]=copySort.top();
iIndex++;
copySort.pop();
}
//cout<<cardData[0]<<" "<<cardData[1]<<" "<<cardData[2]<<" "<<cardData[3]<<endl;
checkSnowballOK();
checkMergeOK();
}
/*if(haveAns>0){
ansSum++;
cout<<cardData[0]<<" "<<cardData[1]<<" "<<cardData[2]<<" "<<cardData[3]<<endl;
haveAns=0;
}*/
return;
}
/*
四个卡牌的次序排序,使用深度优先排序
*/
void dfsCardSort(int *yyx,int indexP){
if(indexP==4){
checkOK();
return;
}
for(int i=0;i<4;i++){
if(!isSort[i]){
isSort[i]=true;
mySort.push(yyx[i]);
// cout<<yyx[i]<<endl;
dfsCardSort(yyx,indexP+1);
mySort.pop();
isSort[i]=false;
}
}
}
/*
输入四个卡牌卡牌的值,去计算是否可以正确运算
*/
bool toAns(int q1,int q2,int q3,int q4){
int yyx[4]={q1,q2,q3,q4};
dfsCardSort(yyx,0);
if(haveAns) return true;
else return false;
}
/*
将卡牌转化为数字,其中0对应10,JQK分别对应11 12 13
*/
bool toInt(char s1,char s2,char s3,char s4){
int q1,q2,q3,q4;
if(s1>'0'&&s1<='9'){
q1=s1-'0';
}
else{
if(s1=='0') q1=10;
if(s1=='J') q1=11;
if(s1=='Q') q1=12;
if(s1=='K') q1=13;
}
if(s2>'0'&&s2<='9'){
q2=s2-'0';
}
else{
if(s2=='0') q2=10;
if(s2=='J') q2=11;
if(s2=='Q') q2=12;
if(s2=='K') q2=13;
}
if(s3>'0'&&s3<='9'){
q3=s3-'0';
}
else{
if(s3=='0') q3=10;
if(s3=='J') q3=11;
if(s3=='Q') q3=12;
if(s3=='K') q3=13;
}
if(s4>'0'&&s4<='9'){
q4=s4-'0';
}
else{
if(s4=='0') q4=10;
if(s4=='J') q4=11;
if(s4=='Q') q4=12;
if(s4=='K') q4=13;
}
// cout<<q1<<" "<<q2<<" "<<q3<<" "<<q4;
if(!toAns(q1,q2,q3,q4)) return false;
else return true;
}
int main(){
char s1,s2,s3,s4;
while(cin>>s1>>s2>>s3>>s4){
haveAns=0;
cout<<endl;
cout<<"答案为:"<<endl;
cout<<endl;
if(!toInt(s1,s2,s3,s4)) cout<<"no ans"<<endl;
}
/*
for(int i=0;i<13*13*13*13;i++){
cardData[0]=i%13+1;
cardData[1]=(i/13)%13+1;
cardData[2]=(i/13/13)%13+1;
cardData[3]=(i/13/13/13)%13+1;
checkOK();
}
cout<<"有多少个解?"<<ansSum;
*/
return 0;
}
-------------------------------------
尊敬的开发者,您好!我是一名初入职场的小小程序员,从事软件开发工作,定期发一些文章来记录自己的学习过程,并分享问题的解决方法。
如果样例代码和文章描述有哪些问题,或者有相关领域想一起讨论,欢迎私信交流。