當前位置:首頁 » 編程語言 » c語言24點講解
擴展閱讀
醫院核酸數據多久才上傳 2022-09-25 13:09:39
機頂盒連接硬碟 2022-09-25 13:09:33

c語言24點講解

發布時間: 2022-08-11 08:38:01

⑴ 1-10 用c語言 算24點 思考過程(思路)

每個游戲設計者對24點的規定可能有些差異,下面就一種規則給你個思路

求24點問題。給定4個正整數,用算術運算符+,-,*,/將這4個正整數連接起來,使其最終結果恰為24。如果能得到24,輸出Yes,否則輸出No。

對於這種問題一種簡單的方法是使用回溯法,先把這四個符號存入一個數組,然後遞歸的調用一個函數,這個函數的內容是一次性用數組的第一個符號將這四個數連完,那麼就是1+2+3+4,看看能不能使結果等於24,這里等於10,不滿足,那麼就把最後那個+換成數組的第二個元素,也就是-,就是1+2+3-4,再計算結果,發現結果等於2,也不符合要求,那麼繼續替換.....直至1+2+3/4,再計算結果,發現結果還是不行,那麼這個時候本函數執行完畢了,因為是遞歸調用,所以返回至上層函數,這時候上層函數所指示的符號位置就是第二個符號了,那麼這個時候就要替換第二個符號了,那麼效果就是1+2-3+4,結果不對,那麼繼續,1+2-3-4,不對,.....直至1/2/3/4,這一過程中如果發現結果等於24那麼說明找到了答案,否則說明所給四個數不能通過四則運算得到24

⑵ C語言算24點

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

char op[3], o[5]="+-*/";

float n[4], on[10];

int used[4] = {0}, top=0, tp=0, x;

void chk(float k);

void search24(int d);

float calc(float n1, float n2, char o);

void make(int i, float p, float q, char o, int d);

int main( void )

{

printf("please input 4 card number: ");

scanf("%f%f%f%f", &n[0], &n[1], &n[2], &n[3]);

search24(0);

printf("No answer. ");

return 0;

}


void chk(float k)

{

if( (tp != 3) || ( fabs(k-24.0) > 0.000001 )) //沒有用完3個運算符或者結果不為24就退出.

return;

for(x=0; x<5; x+=2) //這樣設計是為了使3個選中的符號都可以得到輸出.

printf("%g%c%g=%g ", on[x], op[x/2], on[x+1], //分析得到的.

calc(on[x], on[x+1], op[x/2]));

system("pause");

exit(0);

}

float calc(float n1, float n2, char o)

{

switch(o){

case '+': return (n1+n2);

case '-': return (n1-n2);

case '*': return (n1*n2);

case '/': return (n1/n2);

default: exit(0);

}

}

void make(int i, float p, float q, char o, int d)

{

if(fabs(q)>0.000001 || o!='/') //除數不為0,或者為0的時候不能為除數.

n[i] = calc(p, q, o);

op[tp++] = o;

chk(n[i]);

search24(d+1);

tp--; //因為是全是全局變數,所以在做試驗性的循環遞歸問題時,如果失敗,要在遞歸函數後面重新恢復回原來的值

}

void search24(int d)

{

int i, j, k;

float p, q;

if(d>=3) //控制遞歸深度,就是運算符的輸出個數.

return;

for(i=0; i<4; i++)

for(j=0; j<4; j++)

if( (i!=j)&& (used[i]+used[j] == 0) ) //i!=j是防止重復,(used[i]+used[j] == 0)是防止又再匹配已經用過的j,

//但是i可以新來.

{

used[j] = 1; //j得到匹配之後,賦值為1,表示已經使用

p=n[i];

q=n[j];

on[top++] = p;

on[top++] = q;

for(k=0; k<4; k++) //運算符的循環試用.

make(i, p, q, o[k], d);

n[i] = p; //因為是全是全局變數,所以在做試驗性的循環遞歸問題時,

used[j] = 0; //如果失敗,要在遞歸函數後面重新恢復回原來的值

top -= 2; //

}

}

出處:http://blog.sina.com.cn/s/blog_491de9d60100d5er.html

⑶ 如何用C語言編寫一個24點的游戲

我可以用C++幫你編一個這樣的小程序
但不知道C++算不算得上是C語言?
這個程序有些笨,它無法分辨重復的牌,
只能簡單進行計算。但結果是沒問題的
雖然和你需要的有點出入,但是下面的小程序也算是提供一種思路吧

#include<iostream>
using namespace std;

int main(){
int i1,i2,i3,i4,v,n1,n2;
double t1,t2,t3,t4,choice[4],s1[4],s2[4][4];

cout<<"##########################二十四點全解###################################\n友情提示:A=1,J=11,Q=12,K=13\n";
cout<<"請說出你抽到的第一牌:";
cin>>choice[0];
cout<<"請說出你抽到的第二牌:";
cin>>choice[1];
cout<<"請說出你抽到的第三牌:";
cin>>choice[2];
cout<<"請說出你抽到的第四牌:";
cin>>choice[3];
cout<<"########################## THINKING ###################################\n";
for(i1=0;i1<4;i1++){
t1=choice[i1];
for(i2=0;i2<4;i2++){
if(i2!=i1){
t2=choice[i2];
s1[0]=t1+t2;
s1[1]=t1-t2;
s1[2]=t1*t2;
s1[3]=t1/t2;
for(i3=0;i3<4;i3++){
if(i3!=i1&&i3!=i2){
t3=choice[i3];
for(v=0;v<4;v++)
{s2[v][0]=s1[v]+t3;
s2[v][1]=s1[v]-t3;
s2[v][2]=s1[v]*t3;
s2[v][3]=s1[v]/t3;}
for(i4=0;i4<4;i4++){
if(i4!=i1&&i4!=i2&&i4!=i1){
t4=choice[i4];
for(n1=0;n1<4;n1++)for(n2=0;n2<4;n2++)
if(s2[n1][n2]+t4==24||s2[n1][n2]-t4==24||s2[n1][n2]*t4==24||s2[n1][n2]/t4==24){
cout<<"找到一種組合方案:\n(("<<t1;

if(s1[n1]==t1+t2)cout<<" + ";
if(s1[n1]==t1-t2)cout<<" - ";
if(s1[n1]==t1*t2)cout<<" * ";
if(s1[n1]==t1/t2)cout<<" / ";

if(n2==0)cout<<t2<<") + "<<t3;
if(n2==1)cout<<t2<<") - "<<t3;
if(n2==2)cout<<t2<<") * "<<t3;
if(n2==3)cout<<t2<<") / "<<t3;

if(s2[n1][n2]+t4==24)cout<<") + "<<t4<<" = 24 \n";
if(s2[n1][n2]-t4==24)cout<<") - "<<t4<<" = 24 \n";
if(s2[n1][n2]*t4==24)cout<<") * "<<t4<<" = 24 \n";
if(s2[n1][n2]/t4==24)cout<<") / "<<t4<<" = 24 \n";

}

}}}
}}}}

return 0;
}

⑷ C語言24點的演算法

下面是我自己寫的一個程序:

我的解法是把這個問題分解成了兩個子問題,首先求出4個數字的無重復全排列,放到一個數組裡面,再對沒一個排列情況,從頭到尾窮舉所有的四則運算情況。注意到除法是特殊的,我用x/y表示x除以y,用x|y表示x分之y。注意到,如果窮舉的解得到-24的話,只需要把有減法的地方調換一下順序就可以了,代碼如下
/***********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int index[4]={0,1,2,3};//used to generate subscription collection
int sub[4]; //used in p() only
float f[4]={8.0f,3.0f,3.0f,8.0f};//the 24 point numbers
float fs[24][4];//all possible permutaions of f
float tmp[4]; //used for buf
int g_number=0; //number of permutations
float RES[4];
char op[3];
void p(int idx){//求全排列的函數
if(idx==4){
for(int i=0;i<4;++i){tmp[i]=f[sub[i]];}
for(int g=0;g<g_number;++g){if(memcmp(fs[g],tmp,sizeof(float)*4)==0)return;}
for(int i=0;i<4;++i){fs[g_number][i]=f[sub[i]];}
g_number++;
return;
}
for(int i=0;i<4;++i){//make subscription collections
bool pflag=false;
for(int j=0;j<idx;++j){if(sub[j]==i)pflag=true;}
if(pflag==true)continue;
sub[idx]=index[i];
p(idx+1);
}
}
void solve(int L){//對某個排列,遞歸求所有四則運算的結果,找到就退出
if(L==3){
if(fabs(fabs(RES[L])-24.0f)<0.01f){
printf("Found solution,RES=%f,((%d%c%d)%c%d)%c%d\n",RES[L],
(int)f[0],op[0],
(int)f[1],op[1],
(int)f[2],op[2],
(int)f[3]);
exit(0);
}
return;
}
for(int j=0;j<5;++j){//j judges for operators
if(j==0){RES[L+1]=RES[L]+tmp[L+1];op[L]='+';solve(L+1);}
if(j==1){RES[L+1]=RES[L]-tmp[L+1];op[L]='-';solve(L+1);}
if(j==2){RES[L+1]=RES[L]*tmp[L+1];op[L]='*';solve(L+1);}
if(j==3&&tmp[L+1]!=0)
{RES[L+1]=RES[L]/tmp[L+1];op[L]='/';solve(L+1);}
if(j==4&&RES[L+1]!=0)
{RES[L+1]=tmp[L+1]/RES[L];op[L]='|';solve(L+1);}
}
}
int main(int argc,char* argv[]){//should avoid 0
f[0]=atoi(argv[1]);
f[1]=atoi(argv[2]);
f[2]=atoi(argv[3]);
f[3]=atoi(argv[4]);
p(0);
for(int i=0;i<g_number;++i){
memcpy(tmp,fs[i],sizeof(float)*4);
RES[0]=tmp[0];
for(int t=0;t<4;++t){ printf("%d,",(int)tmp[t]); }
printf("\n");
solve(0);
}
printf("Found no solution :( \n");
return 0;
}

----------編譯運行,運行時的參數就是4個數字
g++ p.cpp && ./a.out 1 5 5 5
1,5,5,5,
Found solution,RES=-24.000000,((1/5)-5)*5
g++ p.cpp && ./a.out 8 3 3 8
8,3,3,8,
Found solution,RES=-24.000006,((8/3)-3)|8
上面這個解寫出來就是
8
--------- = 24
3-(8/3)
主程序為了簡化,省去了對輸入的檢查,樓主可以自己添加。

⑸ 24點游戲C語言

#include<cstdlib>#include<iostream>#include<ctime>using namespace std;
class CCard{private: int m_Pip[5];//一共五張牌 int m_Number;//發了多少張牌 int m_Dollar;//賭本 int m_Gamble;//賭注 int m_Win;//贏局數 int m_Lose;//輸局數 int m_Draw;//平局數public: CCard();//構造函數。 void FirstPlayTwo();//最初的兩張牌 int GetNumber();//返回牌張 int GetPip();//返回點數 void DisplayPip();//依次全部顯示牌面的點數 void DisplayPip(int);//除了第一張牌,依次顯示全部牌面點數(針對計算機牌的顯示) void TurnPlay();//出一張牌。 void Win();//贏了計算賭注 void Lose();//輸了 void Draw();//平局 int SetGamble(int);//設置賭本,賭本不夠返回-1 int GetMoney();//返回錢數 void DisplayInfo();//列印必要的信息 int GetCurrentCard();//返回當前的牌點};
CCard::GetNumber(){ return m_Number;}
CCard::CCard()//構造函數,初始化{ m_Number = 0; m_Dollar = 100;//初始賭注為100美元 for(int i=0;i<5;i++) m_Pip[i] = 0; m_Gamble = 0; m_Win = m_Lose = m_Draw = 0;}
int CCard::GetMoney(){ return m_Dollar;}
void CCard::DisplayInfo()//列印必要的信息{ cout<<"\n\n\n\t\t\t您一共玩了"<<m_Win+m_Lose+m_Draw<<"局 "<<"贏了"<<m_Win<<"局 "<<"輸了"<<m_Lose<<"局 "<<"平局"<<m_Draw<<"次。"<<endl; cout<<"\n\t\t\t\t您的賭本共計有$"<<m_Draw<<"。\n"<<endl;}
int CCard::SetGamble(int gamble){ if(gamble<0) { cout<<"\n輸入金額有誤"<<endl; return -1; } if(m_Dollar-gamble<0) { cout<<"\n金額不足"<<endl; return -1; } else m_Gamble = gamble; m_Dollar -= gamble; return 0;}
void CCard::FirstPlayTwo()//最初兩張牌{ m_Pip[0] = rand()%13+1; m_Pip[1] = rand()%13+1; m_Number = 2;}
int CCard::GetPip(){ int SumPip = 0; for(int i=0;i<m_Number;i++) { SumPip += m_Pip[i]; } return SumPip;}
void CCard::DisplayPip(){ int i; for(i=0;i<m_Number;i++) { cout<<m_Pip[i]<<'\t'; } cout<<endl;}
void CCard::TurnPlay(){ m_Number++; m_Pip[m_Number-1] = rand()%13+1;}
void CCard::Win(){ cout<<"贏家牌面:"; DisplayPip(); cout<<"\n牌面點數:"<<GetPip()<<endl; m_Dollar = m_Dollar + 2 * m_Gamble; m_Win++; cout<<"\n賭本:$"<<m_Dollar<<" 贏了"<<m_Win<<"次 "<<"輸了"<<m_Lose<<"次 "<<"平局"<<m_Draw<<"次"<<endl; cout<<endl; cout<<endl;}
void CCard::Lose(){ m_Lose++; cout<<"\n輸家的牌面:"; DisplayPip(); if(GetPip()>21) cout<<"\t\t\t\t\t\t\t\t暴了!"<<endl; else cout<<"牌面點數:"<<GetPip()<<endl; cout<<"\n賭本:$"<<m_Dollar<<" 贏了"<<m_Win<<"次 "<<"輸了"<<m_Lose<<"次 "<<"平局"<<m_Draw<<"次"<<endl; cout<<endl<<endl;}
void CCard::Draw(){ m_Draw++; m_Dollar += m_Gamble; cout<<"\n平局牌面:"; DisplayPip(); if(GetPip()>21) cout<<"\n暴了!"<<endl; else cout<<"牌面點數:"<<GetPip()<<endl; cout<<"賭本:$"<<m_Dollar<<" 贏了"<<m_Win<<"次 "<<"輸了"<<m_Lose<<"次 "<<"平局"<<m_Draw<<"次"<<endl; cout<<endl<<endl;}
void DisplayRule(void){ cout<<endl<<endl; cout<<"\t※※※※※※※※※※歡迎進入21點游戲世界!※※※※※※※※※※\n\n"; cout<<"\t\t 游戲規則:\n"; cout<<endl; cout<<"\t\t 1.玩家最多可以要5張牌;\n"; cout<<endl; cout<<"\t\t 2.如果牌點數的總數超過21點則暴點,自動判數;\n"; cout<<endl; cout<<"\t\t 3.贏家可得雙倍的賭注;\n"; cout<<endl; cout<<"\t\t 4.計算機方在大於等於16點時不再要牌。\n"; cout<<endl; cout<<"\t※※※※※※※※※※※※※ 祝您好運! ※※※※※※※※※※\n"; cout<<endl<<endl;}
void Judge(CCard &cpu,CCard &player){ cout<<endl; if((cpu.GetPip()>21&&player.GetPip()>21)||cpu.GetPip()==player.GetPip()) { cout<<"\n\n\t\t\t\t\t\t\t\t平局!\n"; cout<<"計算機數據:\t"; cpu.DisplayPip(); cout<<"牌面點數:"<<cpu.GetPip()<<endl; cout<<"\n您的數據:\t"; player.Draw(); cout<<endl; } else if((cpu.GetPip()>21)||(player.GetPip()>cpu.GetPip()&&player.GetPip()<=21)) { cout<<"\n\n\n\t\t\t\t\t\t\t\t恭喜您贏了!\n\n"; cout<<"計算機數據:\t"; cpu.DisplayPip(); cout<<"牌面點數:"<<cpu.GetPip()<<endl; cout<<"\n您的數據:\t"; player.Win(); cout<<endl; } else { cout<<"\n\n\t\t\t\t\t\t\t\t很遺憾您輸了!\n"; cout<<"計算機數據:\t"; cpu.DisplayPip(); cout<<"牌面點數:"<<cpu.GetPip()<<endl; cout<<"\n您的數據:\t"; player.Lose(); cout<<endl; }}void CCard::DisplayPip(int n){ int i; cout<<"[*]"<<'\t'; for(i=1;i<m_Number;i++) cout<<m_Pip[i]<<'\t'; cout<<endl;}
void PlayTurn(CCard &cpu,CCard & player)//玩一局{ char chChoice; int blCpu = 1;//判斷是否要牌 int blPlayer = 1; cpu.FirstPlayTwo();//計算機和玩家各要兩張牌 player.FirstPlayTwo(); do { cout<<"\n您的牌點為:\t"; player.DisplayPip(); cout<<"\n"; cout<<"您的牌面點數是:"<<player.GetPip()<<endl; cout<<"\n計算機的牌點為:\t"; cpu.DisplayPip(1); if(blPlayer) { cout<<"\n\n\t您是否繼續要牌(Y/N)?\t\t\t"; cin>>chChoice; if((chChoice == 'Y'||chChoice == 'y')) { if(player.GetNumber()<5) { player.TurnPlay(); cout<<"\n您要的這張牌是:"<<player.GetPip()<<endl; if(player.GetPip()>21) blPlayer = 0; } else { cout<<"對不起,您已經要了5張牌,不能再要牌了!"; blPlayer = 0; } } if(chChoice=='n'||chChoice=='N') blPlayer = 0; } if(cpu.GetPip()<16&&cpu.GetNumber()<5) { cpu.TurnPlay(); cout<<"\n計算機要牌,牌點是:"<<cpu.GetPip()<<endl; } else blCpu = 0; if(blCpu&&player.GetNumber()<5&&player.GetPip()<21) blPlayer = 1; }while(blCpu||blPlayer); Judge(cpu,player); return ;}
int main(){ srand((unsigned)time(NULL));//初始化隨機數種子 CCard cpu,player; int blLogic; int nMoney;// DisplayRule();// char chChoice; cout<<"是否現在開始游戲(Y/N)?\t\t"; cin>>chChoice; while(chChoice=='Y'||chChoice=='y') { do { cout<<endl; cout<<"\t\t\t您現在有的賭本:$"<<player.GetMoney(); cout<<"\n\n請下注(賭注不能超過賭本);"; cin>>nMoney; blLogic = player.SetGamble(nMoney); if(blLogic) cout<<"您的賭本不夠,請重新下注!\n"; }while(blLogic); PlayTurn(cpu,player);// cout<<"是否繼續21點游戲(Y/N)?\t\t\t"; cin>>chChoice; } player.DisplayInfo(); cout<<"\t\t\t您的選擇是明智的,賭博有礙家庭和睦!\n"; cout<<"\n\n\t\t\t\t歡迎再次使用此程序!"<<endl<<endl<<endl;
return 0;}

⑹ 用c語言編寫24點代碼分析

#include<stdio.h>

double fun(double a1,double a2,int b) //用於嘗試著計算的函數,b為運算控制
{
switch(b)
{
case 0:return (a1+a2);
case 1:return (a1-a2);
case 2:return (a1*a2);
case 3:return (a1/a2);
}
}

void main()
{
int i,j,k,l,n,m,r,save[4];
double num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111;
char sign[5]="+-*/"; //列印時候用的符號,需要和fun函數里的順序保持一致

printf("input 4 numbers:");
for(i=0;i<4;i++)
{
scanf("%lf",num+i); //輸入數據
save[i]=num[i]; //保存原始數據
}

//下面程序的思想,就是利用窮舉(其實就是使用的排列組合方法)來計算可能的組合。
//先把輸入的4個數進行排列(前4個for語句就這個用途)
//再依次插入三個運算符(後3個for語句就這個用途)
//事實上,從這里看,這個程序是不怎樣的。七層循環嵌套,這是編程的大忌。一般循環嵌套最好不要超過兩層。
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(j!=i)
{
for(k=0;k<4;k++)
if(k!=i&&k!=j)
{
for(l=0;l<4;l++)
if(l!=i&&l!=j&&l!=k)
{
for(n=0;n<4;n++)
for(m=0;m<4;m++)
for(r=0;r<4;r++)
{
tem1=fun(num[i],num[j],n);
tem2=fun(tem1,num[k],m);
tem3=fun(tem2,num[l],r);
//以下五種處理方法,涵蓋了有可能的全部運算順序
//這也是本程序最精妙的地方。

if(tem3==24.0)//如果直接算得了24,說明次序不變,直接輸出就是
printf("{(%d%c%d)%c%d}%c%d=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);
else if(tem3==-24.0)//如果算得的是負的,說明需要顛倒第二次運算(第三次運算不可能是加減)
printf("{%d%c(%d%c%d)}%c%d=24\n",save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]);
else if(tem3==1.0/24.0)//如果是倒數,說明需要顛倒最後一次運算(第三次運算同樣不可能是加減)
printf("%d%c{(%d%c%d)%c%d}=24\n",save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]);
else if(tem3==-1.0/24.0)//如果是負倒數,則說明第二次和第三次運算都要顛倒(第三次運算同樣不可能是加或減)
printf("%d%c{%d%c(%d%c%d)}=24\n",save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]);
else
{ //處理()*/+/-()的情況
tem1=fun(num[i],num[j],n);
tem2=fun(num[k],num[l],r);
tem3=fun(tem1,tem2,m);
if(tem3==24.0)
printf("(%d%c%d)%c(%d%c%d)=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);
}
}
}
}
}
}

//後面我再研究了下,發現"第三次不可能是加減法"這種思想是錯誤的,而程序作者在設計的時候,確實是這么認為的,所以,這個程序是有問題的.
//但程序里的主體思想沒有問題,如果需要修改這個錯誤,程序需要在運算順序判斷上下功夫.結果只能取==24的情況.

⑺ 計算24點 C語言

//24點分析(窮舉法)
//
#include
#include
#include

typedef struct D_NODE
{
int data;
struct D_NODE *left,*right;
} NODE24;
NODE24 head;

int res=24;

int maketree(int *src,int *i, NODE24 *p)
{
int d=src[*i];
(*i)++;
switch (d)
{
case '+':
case '-':
case '*':
case '/':
p->left=new NODE24;
p->right=new NODE24;
p->data=d;
maketree(src,i,p->left);
maketree(src,i,p->right);
break;
default:
p->data=d;
p->left=NULL;
p->right=NULL;
}
return 0;
}

int cmaketree(NODE24 *p)
{
int c;
c=getch();
putchar(c);
switch (c)
{
case '+':
case '-':
case '*':
case '/':
p->left=new NODE24;
p->right=new NODE24;
p->data=c;
cmaketree(p->left);
cmaketree(p->right);
break;
default:
p->data=c-'0';
p->left=NULL;
p->right=NULL;
}
return 0;
}

int work(struct D_NODE *d)
{
int res=0;
if (d->left==NULL&&d->right==NULL)
res=d->data;
else
{
int a,b;
a=work(d->left);
b=work(d->right);
switch (d->data)
{
case '+':
res=a+b;//work(d->left)+work(d->right);
break;
case '-':
res=a-b;//work(d->left)-work(d->right);
break;
case '*':
res=a*b;//work(d->left)*work(d->right);
break;
case '/':
if (b!=0)
res=(a%b==0)?a/b:-79;
else
res=-79;
//res=work(d->right)?work(d->left)/work(d->right):-79;
break;
}
}
return res;
}

int destroy(struct D_NODE *d)
{
if (d->left==NULL&&d->right==NULL)
delete d;
else
{
destroy(d->left);
d->left=NULL;
destroy(d->right);
d->right=NULL;
if (d != &head)
delete d;
}
return 0;
}

int show(struct D_NODE *d)
{
if (d->left==NULL && d->right==NULL)
printf("%d",d->data);
else
{
printf("(");
show(d->left);
printf("%c",d->data);
show(d->right);
printf(")");
}
return 0;
}

/* int input()
{
//int buf[30]=,idx=0;
//maketree(buf,&idx,&head);

int buf[20],idx=0;
printf("\nPlease Input:");
for (idx=0;idx<20;idx++)
{
buf[idx]=getch();
printf("%c",buf[idx]);
}
idx=0;
maketree(buf,&idx,&head);
return 0;
} */

#define test(p1,p2,p3,p4,p5,p6,p7) {exp[0]=(p1),exp[1]=(p2), \
exp[2]=(p3),exp[3]=(p4),exp[4]=(p5),exp[5]=(p6),exp[6]=(p7); \
idx=0; \
maketree(exp,&idx,&head); \
if (work(&head)==res) \
{ \
found++;printf("%5d: ",found);show(&head);\
if (!(found%3)) printf("\n");\
} \
destroy(&head);\
}

// printf("%d,%d,%d,%d,%d,%d,%d\n",p1,p2,p3,p4,p5,p6,p7); \

int test24()
{
int num[4],opc[4]=,exp[20];
int i1,i2,i3,i4,ic1,ic2,ic3,idx,found=0;

char prompt[]="24點游戲分析\n易華衛 12/17/2000\n";
printf("%s",prompt);
for (i1=0;i1<4;i1++)
{
printf("請輸入第%d個數字: ",i1+1);
scanf("%d",num+i1);
//num[i1]=num[i1]%13+1;
}
printf("\n你已經輸入了:%d,%d,%d,%d四個數字!\n",num[0],num[1],num[2],num[3]);
printf("\n請輸入要計算的結果值,(當然二十四點就輸入24啦!):");
scanf("%d",&res);
printf("OK! 按任意鍵就可以開始了!\n");
getch();
for (i1=0;i1<4;i1++)
for (i2=0;i2<4;i2++)
if (i2!=i1)
for (i3=0;i3<4;i3++)
if (i3!=i1&&i3!=i2)
for (i4=0;i4<4;i4++)
if (i4!=i1&&i4!=i2&&i4!=i3)
for (ic1=0;ic1<4;ic1++)
for (ic2=0;ic2<4;ic2++)
for (ic3=0;ic3<4;ic3++)
{
test(opc[ic1],opc[ic2],opc[ic3],num[i1],num[i2],num[i3],num[i4]);
test(opc[ic1],opc[ic2],num[i1],opc[ic3],num[i2],num[i3],num[i4]);
test(opc[ic1],opc[ic2],num[i1],num[i2],opc[ic3],num[i3],num[i4]);
test(opc[ic1],num[i1],opc[ic2],opc[ic3],num[i2],num[i3],num[i4]);
test(opc[ic1],num[i1],opc[ic2],num[i2],opc[ic3],num[i3],num[i4]);
}
printf("\n共找到了 %d 條正確的計算方法!(很抱歉,我沒有處理交換率*^_^*)\n",found);
return 0;
}

main()
{
// fflush(stdin);
// input();
// cmaketree(&head);
// printf("\n=%d\n",work(&head));
test24();
return 0;
}

⑻ c語言算24點的這個演算法看不懂,解釋!

哪裡看不懂。

⑼ 24點 C語言程序

在網上找了個代碼,我改了下,符合你的三個要求了。
#include<stdio.h>
double
fun(double
a1,double
a2,int
b)
{switch(b)
{case
0:return
(a1+a2);
case
1:return
(a1-a2);
case
2:return
(a1*a2);
case
3:return
(a1/a2);
}
}
void
main()
{int
i,j,k,l,n,m,r,save[4],flg=1;
double
num[4]={1,1,1,1},tem1,tem2,tem3,abc=1111;
char
sign[5]="+-*/";
printf("輸入四個數:");
for(i=0;i<4;i++)
{scanf("%lf",num+i);
save[i]=num[i];if(save[i]>13)flg=0;}
if(flg)
{
flg=0;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(j!=i)
{for(k=0;k<4;k++)
if(k!=i&&k!=j)
{for(l=0;l<4;l++)
if(l!=i&&l!=j&&l!=k)
{for(n=0;n<4;n++)
for(m=0;m<4;m++)
for(r=0;r<4;r++)
{tem1=fun(num[i],num[j],n);
tem2=fun(tem1,num[k],m);
tem3=fun(tem2,num[l],r);
if(tem3==24.0)
{printf("{(%d%c%d)%c%d}%c%d=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);return;}
else
if(tem3==-24.0)
{printf("{%d%c(%d%c%d)}%c%d=24\n",save[k],sign[m],save[i],sign[n],save[j],sign[r],save[l]);return;}
else
if(tem3==1.0/24.0)
{printf("%d%c{(%d%c%d)%c%d}=24\n",save[l],sign[r],save[i],sign[n],save[j],sign[m],save[k]);return;}
else
if(tem3==-1.0/24.0)
{printf("%d%c{%d%c(%d%c%d)}=24\n",save[l],sign[r],save[k],sign[n],save[i],sign[m],save[j]);return;}
else
{tem1=fun(num[i],num[j],n);
tem2=fun(num[k],num[l],r);
tem3=fun(tem1,tem2,m);
if(tem3==24.0)
{printf("(%d%c%d)%c(%d%c%d)=24\n",save[i],sign[n],save[j],sign[m],save[k],sign[r],save[l]);return;}
}
}
}
}
}
}
if(!flg)
printf("NO
ANSWER\n");
}

⑽ 關於24點的C語言代碼,能直接使用的,注釋最好多一點,以便理解

這道題目如果沒其他較好的辦法就採用暴力窮舉解決。根據給定的4個數,得出兩棵不同構的語法樹。
O O
/ \ / \
O O 和 o O
/ \ / \ / \
o o o o o O
/ \
o o
分別得出的逆波蘭式為:ooOooOO和ooooOOO,其中o為操作數,O為運算符。然後對這兩種形式的逆波蘭式進行窮舉並計算即可。對於第一種逆波蘭式共有4!*4^3=4*3*2*4*4*4=1536種不同情況,第二種逆波蘭式也有1536種不同情況。因此,若無解,則共循環測試3072次。
include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
char RPN[7];
char operdata[24][4] = {{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1},/*操作數的24種不同排列*/
{1,0,2,3},{1,0,3,2},{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0},
{2,1,0,3},{2,1,3,0},{2,0,1,3},{2,0,3,1},{2,3,1,0},{2,3,0,1},
{3,1,2,0},{3,1,0,2},{3,2,1,0},{3,2,0,1},{3,0,1,2},{3,0,2,1}
};
char oper[64][3]={{-1,-1,-1},{-1,-1,-2},{-1,-1,-3},{-1,-1,-4},/*操作符的64種不同排列*/
{-1,-2,-1},{-1,-2,-2},{-1,-2,-3},{-1,-2,-4}, /*-1~-4分別表示:+ - * / */
{-1,-3,-1},{-1,-3,-2},{-1,-3,-3},{-1,-3,-4},
{-1,-4,-1},{-1,-4,-2},{-1,-4,-3},{-1,-4,-4},
{-2,-1,-1},{-2,-1,-2},{-2,-1,-3},{-2,-1,-4},
{-2,-2,-1},{-2,-2,-2},{-2,-2,-3},{-2,-2,-4},
{-2,-3,-1},{-2,-3,-2},{-2,-3,-3},{-2,-3,-4},
{-2,-4,-1},{-2,-4,-2},{-2,-4,-3},{-2,-4,-4},
{-3,-1,-1},{-3,-1,-2},{-3,-1,-3},{-3,-1,-4},
{-3,-2,-1},{-3,-2,-2},{-3,-2,-3},{-3,-2,-4},
{-3,-3,-1},{-3,-3,-2},{-3,-3,-3},{-3,-3,-4},
{-3,-4,-1},{-3,-4,-2},{-3,-4,-3},{-3,-4,-4},
{-4,-1,-1},{-4,-1,-2},{-4,-1,-3},{-4,-1,-4},
{-4,-2,-1},{-4,-2,-2},{-4,-2,-3},{-4,-2,-4},
{-4,-3,-1},{-4,-3,-2},{-4,-3,-3},{-4,-3,-4},
{-4,-4,-1},{-4,-4,-2},{-4,-4,-3},{-4,-4,-4}
};
void Swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
int compute(char *a) //如果是一個解,則返回1,否則返回0,a是一個逆波蘭式
{
int stack[10], top = -1, i, s1, s2;
for(i = 0; i < 7; i++)
{
if(a[i] > 0 && a[i] < 11) stack[++top] = a[i];
else {
s1 = stack[top--];
s2 = stack[top--];
if(s1 < s2) Swap(s1, s2);
switch(a[i]) {
case -1: stack[++top] = s1 + s2;
break;
case -2: stack[++top] = s1 - s2;
break;
case -3: stack[++top] = s1 * s2;
break;
case -4: if((s1 && s2) && (s1 % s2 == 0)) stack[++top] = s1 / s2;
else return 0;
}
}
}
return (stack[top] == 24);
}
void cout(char *a)
{
int stack[10], top = -1, i, s1, s2;
for(i = 0; i < 7; i++)
{
if(a[i] > 0 && a[i] < 11) stack[++top] = a[i];
else {
s1 = stack[top--];
s2 = stack[top--];
if(s1 < s2) Swap(s1, s2);
switch(a[i]) {
case -1: stack[++top] = s1 + s2;
printf("%d + %d = %d\t", s1, s2, s1+s2);
break;
case -2: stack[++top] = s1 - s2;
printf("%d - %d = %d\t", s1, s2, s1-s2);
break;
case -3: stack[++top] = s1 * s2;
printf("%d * %d = %d\t", s1, s2, s1*s2);
break;
case -4: if(s1 % s2 == 0) stack[++top] = s1 / s2;
printf("%d / %d = %d\t", s1, s2, s1/s2);
}
}
}
}
void main( )
{
char data[4], i, j, k, ch;
int flag;
srand(time(0));
printf("若退出,請按\'n\'鍵,否則請按其他鍵繼續\n");
ch = getch( );
while(ch != 'n')
{
flag = 0;
for(i = 0; i < 4; i++)
{
data[i] = rand( ) % 10 + 1;
printf("%d ", data[i]);
}
printf("\n");
for(i = 0; i < 24 && !flag; i++)
{
RPN[0] = data[operdata[i][0]];
RPN[1] = data[operdata[i][1]];
RPN[3] = data[operdata[i][2]];
RPN[4] = data[operdata[i][3]];
for(j = 0; j < 64 && !flag; j++)
{
RPN[2] = oper[j][0];
RPN[5] = oper[j][1];
RPN[6] = oper[j][2];

flag = compute(RPN);
if(flag)
{
cout(RPN);
}
}
RPN[0] = data[operdata[i][0]];
RPN[1] = data[operdata[i][1]];
RPN[2] = data[operdata[i][2]];
RPN[3] = data[operdata[i][3]];
for(j = 0; j < 64 && !flag; j++)
{
RPN[4] = oper[j][0];
RPN[5] = oper[j][1];
RPN[6] = oper[j][2];

flag = compute(RPN);
if(flag)
{
cout(RPN);
}
}
}
if(!flag) printf("無解\n");
printf("若退出,請按\'n\'鍵,否則請按其他鍵繼續\n");
ch = getch( );
}
}