| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2064 人关注过本帖
标题:[求助]24点(扑克牌)游戏
只看楼主 加入收藏
lemonblood
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-6-18
收藏
 问题点数:0 回复次数:8 
[求助]24点(扑克牌)游戏

输入1-10之间的4个数,每个数只能出现一次。无论使用+-*/或者(),使最后结果等于24;输出所有能实现的算法。
很复杂吧,问了N个人,发了N张贴,求高人一定帮一下。

搜索更多相关主题的帖子: 扑克牌 游戏 算法 高人 
2006-06-22 20:47
–★–
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1512
专家分:0
注 册:2006-5-1
收藏
得分:0 
/*24points.c */
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define EPS 1e-8
#define DIN double /*或int*/
#define MAX 10 /*或13 */
char strs[12],operator[]="+-*/",opch[][3]={"+","-","×","÷"};
DIN ans(int ith,DIN x,DIN y)
{ switch(operator[ith-1])
{ case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': if(y)if(sizeof(DIN)==sizeof(int)&&(int)x%(int)y==0
||sizeof(DIN)==sizeof(double))return x/y;
default : return -1; }
}
int ok2(DIN x,DIN y)
{ int ix; for(ix=1; ix<=4; ix++)
if(fabs(ans(ix,x,y)-24)<EPS)return(ix);
return(0);
}
int ok3(DIN a,DIN b,DIN c)
{ int i,j,k; DIN x[3];
x[0]=a; x[1]=b; x[2]=c;
for(i=0; i<3; i++)
for(j=0; j<3; j++)if(j!=i)
for(k=0; k<3; k++)if(k!=i && k!=j)
{ int ix,imid; DIN y;
for(ix=1; ix<=4; ix++)
{ y=ans(ix,x[i],x[j]); if(y<=0)continue;
if((imid=ok2(y,x[k]))!=0)
{ if(i==0)printf("(%s%s%d)%s%d\n",strs,opch[ix-1],
(int)x[j],opch[imid-1],(int)x[k]);
else if(j==0)printf("(%d%s%s)%s%d\n",(int)x[i],opch[ix-1],
strs,opch[imid-1],(int)x[k]);
else if(k==0)printf("(%d%s%d)%s%s\n",(int)x[i],opch[ix-1],
(int)x[j],opch[imid-1],strs);
return(1);
}
}
} return(0);
}
int point24(int p[4])
{ int a,b,c,d,i,ix; DIN y;
for(a=0; a<4; a++)
for(b=0; b<4; b++)if(b!=a)
for(c=0; c<4; c++)if(c!=a && c!=b)
for(d=0; d<4; d++)if(d!=a && d!=b && d!=c)
for(ix=1; ix<=4; ix++)
{ y=ans(ix,p[a],p[b]); if(y<=0)continue;
strs[0]='('; itoa(p[a],&strs[1],10);
strcat(strs,opch[ix-1]); i=strlen(strs);
itoa(p[b], &strs[i],10); i=strlen(strs);
strs[i]=')'; strs[i+1]='\0';
if(ok3(y,p[c],p[d]))return(1);
} return(0);
}
main( )
{ int p[4],total,cannot; printf("4 cards: ");
scanf("%d%*c%d%*c%d%*c%d",p,p+1,p+2,p+3);
point24(p);
/************以下做全部解********************************************
total=0; cannot=0;
for(p[0]= 1 ; p[0]<=MAX; p[0]++)
for(p[1]=p[0]; p[1]<=MAX; p[1]++)
for(p[2]=p[1]; p[2]<=MAX; p[2]++)
for(p[3]=p[2]; p[3]<=MAX; p[3]++)
{ total++; if(!point24(p)){ cannot++;
printf("%d,%d,%d,%d\n",p[0],p[1],p[2],p[3]); }
} printf("MAX=%d,TOTAL=%d,CANNOT=%d\n",MAX,total,cannot);
*********************************************************************/
}

落霞与孤鹜齐飞,秋水共长天一色! 心有多大,路有多宽。三教九流,鸡鸣狗盗。兼收并蓄,海纳百川。
2006-06-22 20:54
lemonblood
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2006-6-18
收藏
得分:0 

厉害,这么快,非常感谢

2006-06-22 21:19
–★–
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1512
专家分:0
注 册:2006-5-1
收藏
得分:0 
回复:(lemonblood)厉害,这么快,非常感谢
以下是引用lemonblood在2006-6-22 21:19:49的发言:

厉害,这么快,非常感谢

别夸我,因为编得很滥,真的。
早晚要编写称心如意的:
1。24点游戏程序
2。石子堆的归并
。。。。。。。。。。。。


落霞与孤鹜齐飞,秋水共长天一色! 心有多大,路有多宽。三教九流,鸡鸣狗盗。兼收并蓄,海纳百川。
2006-06-23 08:35
仁者无敌
Rank: 1
等 级:新手上路
帖 子:199
专家分:0
注 册:2006-3-5
收藏
得分:0 
得好好看看二楼写的程序!

I am a programmer !
2006-06-24 16:13
仁者无敌
Rank: 1
等 级:新手上路
帖 子:199
专家分:0
注 册:2006-3-5
收藏
得分:0 
二楼的高手能不能说说算法啊?

I am a programmer !
2006-06-24 16:15
–★–
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:1512
专家分:0
注 册:2006-5-1
收藏
得分:0 

廿四点游戏程序。

在1~10范围内共有715种出牌。当符号常量DIN==int时,有159种无法实现24点;当DIN==double时,有153种无法实现24点。实数除法比整除新增的6组解如下

(5-1/5)×5 (2+4/10)×10 (5-2/10)×5

(2+10/7)×7 (3+3/7)×7 (4-4/7)×7

/*24points.c*/

#include<math.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define EPS 1e-8

#define DIN double /*或int*/

#define MAX 10 /*或13 */

char strs[12],operator[ ][3]={“+”,“-”,“×”,“÷”};

DIN ans(int iop,DIN x,DIN y)

{ switch(iop)

{ case 1 : return x+y;

case 2 : return x-y;

case 3 : return x*y;

case 4 : if(y)if(sizeof(DIN)==sizeof(int)&&(int)x%(int)y==0

||sizeof(DIN)==sizeof(double))return x/y;

default: return -1; }

}

int ok2(DIN x,DIN y)

{ int ix; for(ix=1; ix<=4; ix++)

if(fabs(ans(ix,x,y)-24)<EPS)return(ix);

return(0);

}

int ok3(DIN a,DIN b,DIN c)

{ int i,j,k; DIN x[3];

x[0]=a; x[1]=b; x[2]=c;

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

for(j=0; j<3; j++)if(j!=i)

for(k=0; k<3; k++)if(k!=i && k!=j)

{ int ix,imid; DIN y;

for(ix=1; ix<=4; ix++)

{ y=ans(ix,x[i],x[j]); if(y<=0)continue;

if((imid=ok2(y,x[k]))!=0)

{ if(i==0)printf(“(%s%s%d)%s%d\n”,strs,operator[ix-1],

(int)x[j],operator[imid-1],(int)x[k]);

else if(j==0)printf(“(%d%s%s)%s%d\n”,(int)x[i],operator[ix-1],

strs,operator[imid-1],(int)x[k]);

else if(k==0)printf(“(%d%s%d)%s%s\n”,(int)x[i],operator[ix-1],

(int)x[j],operator[imid-1],strs);

return(1);

}

}

} return(0);

}

int point24(int p[4])

{ int a,b,c,d,i,ix; DIN y;

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

for(b=0; b<4; b++)if(b!=a)

for(c=0; c<4; c++)if(c!=a && c!=b)

for(d=0; d<4; d++)if(d!=a && d!=b && d!=c)

for(ix=1; ix<=4; ix++)

{ y=ans(ix,p[a],p[b]); if(y<=0)continue;

strs[0]=‘(’; itoa(p[a],&strs[1],10);

strcat(strs,operator[ix-1]); i=strlen(strs);

itoa(p[b], &strs[i],10); i=strlen(strs);

strs[i]=‘)’; strs[i+1]=‘\0’;

if(ok3(y,p[c],p[d]))return(1);

} return(0);

} /* itoa(p[a],&strs[1],10)将p[a]的值按10进制转换成字符串存入&strs[1]*/

main( )

{ int p[4],total,cannot; printf(“4 cards: ”);

scanf(“%d%*c%d%*c%d%*c%d”,p,p+1,p+2,p+3);

point24(p);

/************以下做全面检测********************************************

total=0; cannot=0;

for(p[0]= 1 ; p[0]<=MAX; p[0]++)

for(p[1]=p[0]; p[1]<=MAX; p[1]++)

for(p[2]=p[1]; p[2]<=MAX; p[2]++)

for(p[3]=p[2]; p[3]<=MAX; p[3]++)

{ total++; if(!point24(p)){ cannot++;

printf(“%d,%d,%d,%d\n”,p[0],p[1],p[2],p[3]); }

} printf(“MAX=%d,TOTAL=%d,CANNOT=%d\n”,MAX,total,cannot);

***********************************************************************/

}

运行情况:若键入 1,5,5,5 ↙ 则输出 (5-(1÷5))×5

若键入 4,4,7,7 ↙ 则输出 (4-(4÷7))×7

若键入 4,9,6,12 ↙ 则输出 ((4+12)×9)÷6

若键入 4,9,6,11 ↙ 无输出 (表示无法形成24点)

对以上程序ex6-49.c的几点说明。①主函数提示用户输入4张牌的点数并将它们存入数组p[],然后调用point24函数。②point24函数是一5重循环,外围4重产生4张牌的全排列p[a]p[b]p[c]p[d];内层ix循环(通过ans函数)先后产生p[a],p[b]的和差积商,并将它存入y变量(这样一来就退化为“3张牌”问题)…(略去细节)…然后调用ok3函数。若ok3返回1则立即从5重循环中退出并返回1;否则继续循环。5重循环完毕若仍未果则返回0。③ok3函数的思路与point24()如出一辙。3层外循环产生“3张牌”x[i]x[j]x[k]的全排列,内层ix(此ix非彼ix)循环将x[i],x[j]的和差积商之一存入(本地的)y变量,从而退化为“2张牌”的问题。接着调用ok2函数,若ok2返回非零值则显示该24点问题的一种解法,然后从4重循环中退出并返回1;否则继续循环。若4重循环完未果则返回0。④ok2函数确定“2张牌”能否形成24点,若不能则返回0,否则返回1~4(加减乘除)中的某个数。⑤ans函数将加减乘除四则运算序数化为1~4,以便纳入循环操作的轨道。


落霞与孤鹜齐飞,秋水共长天一色! 心有多大,路有多宽。三教九流,鸡鸣狗盗。兼收并蓄,海纳百川。
2006-06-24 16:37
cd_tiger
Rank: 1
等 级:新手上路
帖 子:29
专家分:0
注 册:2006-6-10
收藏
得分:0 

--------------------Configuration: tc - Win32 Debug--------------------
Compiling...
tc.cpp
E:\test\c\test\tc.cpp(9) : error C2440: 'initializing' : cannot convert from 'char [5]' to 'char'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
E:\test\c\test\tc.cpp(11) : error C2543: expected ']' for operator '[]'
E:\test\c\test\tc.cpp(11) : error C2146: syntax error : missing ')' before identifier 'ith'
E:\test\c\test\tc.cpp(11) : error C2143: syntax error : missing ';' before ']'
E:\test\c\test\tc.cpp(11) : warning C4552: '-' : operator has no effect; expected operator with side-effect
E:\test\c\test\tc.cpp(11) : warning C4060: switch statement contains no 'case' or 'default' labels
E:\test\c\test\tc.cpp(11) : error C2059: syntax error : ')'
E:\test\c\test\tc.cpp(12) : error C2143: syntax error : missing ';' before '{'
E:\test\c\test\tc.cpp(12) : error C2046: illegal case
E:\test\c\test\tc.cpp(13) : error C2046: illegal case
E:\test\c\test\tc.cpp(14) : error C2046: illegal case
E:\test\c\test\tc.cpp(15) : error C2046: illegal case
E:\test\c\test\tc.cpp(17) : error C2047: illegal default
E:\test\c\test\tc.cpp(74) : warning C4508: 'main' : function should return a value; 'void' return type assumed
Error executing cl.exe.

tc.obj - 11 error(s), 3 warning(s)

2006-06-24 16:38
caibuen
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2007-6-20
收藏
得分:0 
2007-06-20 10:37
快速回复:[求助]24点(扑克牌)游戏
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017628 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved