//
/*
6-6
二十壹點遊戲
*/
#包含“conio.h”
#包含" stdlib.h "
#包含“time.h”
#包含“math.h”
#include "string.h"/*
從壹副撲克牌中任選四張。
2-10按點數計算(為方便起見,10用T表示),J、Q、K、A統壹按1計算。
要求通過加減乘除四則運算得到數字24。
這個程序可以隨機抽卡,用試錯法求解。
*/void GivePuzzle(char* buf)
{
char card[] = {'A ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',' 9 ',' T ',' J ',' Q ',' K ' };for(int I = 0;我& lt4;i++){
buf[I]= card[rand()% 13];
}
}
無效洗牌(char * buf)
{
for(int I = 0;我& lt5;i++){
int k = rand()% 4;
char t = buf[k];
buf[k]= buf[0];
buf[0]= t;
}
}
int GetCardValue(int c)
{
if(c=='T ')返回10;
if(c & gt;= ' 0 ' & amp& ampc & lt='9 ')返回c-' 0 ';
返回1;
}
char GetOper(int n)
{
開關(n)
{
案例0:
返回“+”;
案例1:
返回'-';
案例二:
返回“*”;
案例三:
返回“/”;
} return“”;
} double my calc(double op 1,double op2,int oper)
{
開關(操作)
{
案例0:
返回op 1+op2;
案例1:
返回op 1-op2;
案例二:
返回op 1 * op2;
案例三:
if(fabs(op2)>0.0001)
返回op 1/op2;
其他
返回100000;
}返回0;
}
void MakeAnswer(char* answer,int type,char* question,int* oper)
{
char p[4][3];
for(int I = 0;我& lt4;i++)
{
if(問題[i] == 'T ')
strcpy(p[i]," 10 ");
其他
sprintf(p[i]," %c ",問題[I]);
}
開關(類型)
{
案例0:
sprintf(答案," %s %c (%s %c (%s %c %s))",
p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);
打破;
案例1:
sprintf(答案," %s %c ((%s %c %s) %c %s)",
p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);
打破;
案例二:
sprintf(答案,"(%s %c %s) %c (%s %c %s)",
p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);
打破;
案例三:
sprintf(答案,“((%s %c %s) %c %s) %c %s”,
p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);
打破;
案例4:
sprintf(答案,"(%s %c (%s %c %s)) %c %s ",
p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);
打破;
}
}
bool TestResolve(char* question,int* oper,char*答案)
{
//等待考生完成。
int type[5]={0,1,2,3,4 };//計算類型
雙p[4];
double sum = 0;
//
for(int I = 0;我& lt4;I++) //循環獲得積分。
{
p[I]= GetCardValue(int(question[I]));
} for(I = 0;我& lt5;i++)
{
MakeAnswer(答案,類型[i],問題,操作);//獲得可能的答案
開關(類型[i])
{
案例0:
sum=MyCalcu(p[0],MyCalcu( p[1],MyCalcu(p[2],p[3],oper[2]),oper[1],oper[0]);//A*(B*(c*D))
打破;
案例1:
sum=MyCalcu(p[0],MyCalcu(MyCalcu(p[1],p[2],oper[1]),p[3],oper[2],oper[0]);//A *(B * C)* D)
打破;
案例二:
sum=MyCalcu(MyCalcu(p[0],p[1],oper[0]),MyCalcu(p[2],p[3],oper[2],oper[1]);// (A*B)*(C*D)
打破;
案例三:
sum = my calcu(my calcu(my calcu(p[0],p[1],oper[0]),p[2],oper[1]),p[3],oper[2]);//((A*B)*C)*D
打破;
案例4:
sum=MyCalcu(MyCalcu(p[0],MyCalcu(p[1],p[2],oper[1]),oper[0],p[3],oper[2]);//(A*(B*C))*D
打破;
}
if(sum==24)返回true
}
返回false
}
/*
使用隨機試錯法:是通過隨機數生成加減乘除組合,並通過大量測試命中的解決方案。
提示:
1.需要考慮用括號控制計算順序的問題,比如:(10-4) * (3+A),其實計算順序的個數是有限的:
A*(B*(c*D))
a *(B * C)* D)
(A*B)*(C*D)
((A*B)*C)*D
(A*(B*C))*D
2.需要考慮計算結果是壹個分數的情況:(3+(3/7)) * 7。
3.標題中卡片的位置可以隨意交換。
*/
bool TryResolve(char* question,char* answer)
{
int oper[3];//存儲運算符,0:加法1:減法2:乘法3:除法。
for(int I = 0;我& lt1000 * 1000;i++)
{
//打亂卡片的順序
洗牌(問題);
//隨機生成的運算符
for(int j = 0;j & lt3;j++)
oper[j]= rand()% 4;if( TestResolve(question,oper,answer))返回true
}返回false
}
int main(int argc,char* argv[])
{
//初始化隨機種子
srand((無符號)時間(空));char buf 1[4];//主題
char buf 2[30];//回答
printf(" * * * * * * * * * * * * * * * * * * * * * * * * * * * \ n ");
Printf("計算24 \ n ");
Printf("A J Q K按1計算,其他按卡點計算\ n ");
Printf("目標是通過四次運算組合結果:24 \ n ");
printf(" * * * * * * * * * * * * * * * * * * * * * * * * * \ n \ n ");
for(;;)
{
give puzzle(buf 1);//給出壹個問題
printf(" Title:");
for(int j = 0;j & lt4;j++){
if( buf1[j] == 'T ')
printf(" 10 ");
其他
printf("%c ",buf 1[j]);
} printf(" \ n按任意鍵查看答案...\ n ");
getch();If (try resolve (buf1,buf 2))//解決問題
Printf ("reference: %s\n ",buf 2);
其他
Printf("可能無解...\ n ");Printf("按任意鍵進入下壹個主題,按X鍵退出...\ n ");
if(getch()= = ' x ')break;
}返回0;
}