24点游戏 C语言代码
算法分析:总共4个数字a,b,c,d那么需要三条算式 运算三次 判断结果是否为24第一步:循环从 a b c d 取两个数做+ - * / 四次运算 剩下新的 a b c 三个数第二步:循环从 a b c 取两个数做+ - * / 四次运算 剩下新的 a b c 两个数第三步:循环从 a b 取两个数做+ - * / 四次运算 判断结果是否为24算法缺点:这样出来的解法会有重复的算式,也就是说同一
·
算法分析:
总共4个数字a,b,c,d
那么需要三条算式 运算三次 判断结果是否为24
第一步:循环从 a b c d 取两个数做+ - * / 四次运算 剩下新的 a b c 三个数
第二步:循环从 a b c 取两个数做+ - * / 四次运算 剩下新的 a b 两个数
第三步:循环从 a b 取两个数做+ - * / 四次运算 判断结果是否为24
算法缺点:
这样出来的解法会有重复的算式,也就是说同一条算式,却出来了不同的解法
举个例子
(a+b)/ (c*d)
我的算法会产生两种同样的解法:
①
a+b=x
c*d=y
x/y=z
②
c*d=x
a+b=y
x/y=z
算法优点
节省我们实际现实看牌的时间
这样的解法很符合我们实际的拍牌解答的过程
如果输出一条含有括号的、复杂一点的算式 我们实际看起来也还得想一想先拍哪两张牌
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<windows.h>
char sign[3]; //三条式子的三个符号
int n[3][2]; //三条式子的三对运算数
int cnt=0; //记录第几种解法
int option(int a,int b) // 计算除法 避免小数除以大数
{
int c;
if(a<b){ //大数排前面 方便后面做除法
c=a;
a=b;
b=c;
}
return (a/b) ;
}
int pd(int a,int b) //是否做除法的判断
{
int c;
if(a<b){ //大数排前面 方便后面做除法
c=a;
a=b;
b=c;
}
if((a*b!=0)&&(a%b==0)){
return 1;
}
else return 0;
}
int cal(int a,char x,int b)
{
if ( x=='+' ) return a+b;
if ( x=='-' ) return abs(a-b);
if ( x=='*' ) return a*b;
if ( x=='/' ) return a/b;
}
void print()
{
int i,t;
int temp;
// int l,j;
// for (l=0;l<3;l++){
// printf("第%d条 ",l+1) ;
// for(j=0;j<3;j++){
// printf("%c ",sign[l][j]);
// if (j==2) printf("\n");
// }
// }
// for (t=0;t<3;t++){
// printf("第%d条 %d %c %d\n",t+1,n[t][0],sign[t],n[t][1]);
// }
cnt++;
printf("**********************解法%d**********************\n",cnt);
for (t=0;t<3;t++){
if(sign[t]=='-'||sign[t]=='/'){
if(n[t][0]<n[t][1]){
int a;
a=n[t][0];
n[t][0]=n[t][1];
n[t][1]=a;
}
}
temp=cal(n[t][0],sign[t],n[t][1]);
printf("%d%c%d=%d\n",n[t][0],sign[t],n[t][1],temp);
}
}
void step3(int num3[4])
{
int i;
int temp3[4];
int *u=temp3;
int count;
for (i=1;i<=4;i++){
// i=3; //******调试*******
memcpy(temp3,num3,sizeof(int)*2); //还原为原来的数组
switch (i) //加减乘除四次操作 记录第二条式子
{
n[2][0]=*(u+0);
n[2][1]=*(u+1);
case 1:
sign[2]='+';
count=*(u+0) + *(u+1);
break;
case 2:
sign[2]='-';
count=abs(*(u+0) - *(u+1));
break;
case 3:
sign[2]='*';
count=*(u+0) * *(u+1);
break;
case 4:
if(pd(*(u+0) , *(u+1))){
sign[2]='/';
count=option(*(u+0) , *(u+1));
}
break;
}
if(count==24)
{
print();
count=0;
}
}
}
void step2(int a,int b,int num2[4])
{
int i,cf=1;
int temp2[4];
int *u=temp2;
for (i=1;i<=4;i++){
cf=1;
memcpy(temp2,num2,sizeof(int)*3); //还原为原来的数组
switch (i) //加减乘除四次操作 记录第二条式子
{
case 1:
sign[1]='+';
*(u+a)=*(u+a) + *(u+b);
break;
case 2:
sign[1]='-';
*(u+a)=abs(*(u+a) - *(u+b));
break;
case 3:
sign[1]='*';
*(u+a)=*(u+a) * *(u+b);
break;
case 4:
if(cf=pd(*(u+a) , *(u+b))){ //记录是否做除法 此步没有做运算 那么不用继续进行下去了
sign[1]='/';
*(u+a)=option(*(u+a),*(u+b));
}
break;
}
if(cf){
int *q;
for(q=u+b;q<u+2;q++){ //把后面的数往前移一位 还剩2个数
*q=*(q+1);
}
n[2][0]=temp2[0];
n[2][1]=temp2[1];
// printf("算第 2 遍后的牌面:%d %d\n",temp2[0],temp2[1]) ;
step3(temp2) ;
// if (i==4) printf("\n") ;
}
}
}
void step1(int a,int b,int num1[4]) //num1为接入数组,temp[]为输出数组
{
int i,cf;
int temp1[4];
int *u=temp1;
for (i=1;i<=4;i++){
cf=1;
memcpy(temp1,num1,sizeof(int)*4); //恢复原来的数组进行处理
switch (i) //加减乘除四次操作 记录第一条式子
{
case 1:
sign[0]='+';
*(u+a)=*(u+a) + *(u+b);
break;
case 2:
sign[0]='-';
*(u+a)=abs(*(u+a) - *(u+b));
break;
case 3:
sign[0]='*';
*(u+a)=*(u+a) * *(u+b);
break;
case 4:
if(cf=pd(*(u+a) , *(u+b))){ //记录是否做除法 此步没有做运算 那么不用继续进行下去了
sign[0]='/';
*(u+a)=option(*(u+a),*(u+b));
}
break;
}
if (cf){
int *q;
for(q=u+b;q<u+3;q++){ //从第b个把后面的数往前移一位 还剩3个数
*q=*(q+1);
}
int l,j;
for(l=0;l<3;l++){
for(j=l+1;j<3;j++){
n[1][0]=temp1[l];
n[1][1]=temp1[j];
// printf("算第 1 遍后的牌面:%d %d %d\n",temp1[0],temp1[1],temp1[2]) ;
step2(l,j,temp1) ;
}
}
}
}
}
int main(void){
int num[4];
void step1(int,int,int temp1[]);
void step2(int,int,int temp2[]);
void step3(int temp3[]);
void print();
int cal(int ,char,int );
int pd(int,int);
printf("****************************\n") ;
printf("* *\n") ;
printf("* 这里是24点游戏外挂 *\n") ;
printf("* *\n") ;
printf("****************************\n") ;
loop: printf("请输入四个整数 (退出游戏:输入0 再按回车)\n");
cnt =0;
int i;
for (i=0;i<4;i++){ //读入四个整数
scanf("%d",&num[i]);
if(num[i]==0) goto out;
}
int l,j;
for(l=0;l<4;l++){
for(j=l+1;j<4;j++){
n[0][0]=num[l];
n[0][1]=num[j];
//printf("开始的牌面:%d %d %d %d\n",num[0],num[1],num[2],num[3]) ;
step1(l,j,num);
}
}
if(cnt==0) printf("淦!算我半天,这组数没解哇\n") ;
printf("\n");
goto loop;
out: //程序结束出口
return 0;
}
更多推荐
已为社区贡献2条内容
所有评论(0)