导航:首页 > 源码编译 > 24点算法编程

24点算法编程

发布时间:2024-05-24 15:08:28

Ⅰ 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)
主程序为了简化,省去了对输入的检查,楼主可以自己添加。

python编程:任意输入4个正整数,编程24点

from __future__ import division

import itertools
n = raw_input('input 4 number sep by comma: 1,2,3,4 -> ')
t = list(itertools.permutations(n.split(','),4))
x = list(itertools.proct(* (['+', '-', '*', '/'],) * 3))
for r in t:
for i in x:
if eval(("(((%s%s%s)%s%s)%s%s)") % (r[0],i[0], r[1], i[1], r[2], i[2], r[3])) == 24 :
print ("(((%s%s%s)%s%s)%s%s)=24") % (r[0],i[0], r[1], i[1], r[2], i[2], r[3])

暴力法行么?

Ⅲ 二十四点算法是什么

先取三个数,使它的结果为24,容易想到2×7+10=24,这样一来,由此构造一个带分数,使它含有2、7、10这个分数,2或这个带分数乘以7其结果为24,列式为(2+10÷7)×7=24

Ⅳ C++ 编程,24点游戏

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<ctime>
usingnamespacestd;

intin[5];

intcalc(intoperName,intx,inty)
{
if(operName==1)//+
{
returnx+y;
}

if(operName==2)//-
{
if(x-y<=0)
{
return-3456731;
}

returnx-y;
}

if(operName==3)//*
{
if(x*y<=0)
{
return-464652;
}

returnx*y;
}

if(operName==4)///
{
if(x*y==0||x<y||x%y!=0)
{
return-5643212;
}

returnx/y;
}
}

charoper[]={'!','+','-','*','/'};

intrandom()
{
returnrand()%12+1;
}

intmain()
{
srand(time(NULL));

cout<<"Initialnumbersare:";
for(inti=1;i<=4;i++)
{
in[i]=random();
cout<<in[i]<<"";
}
cout<<endl;

sort(in+1,in+5);

do
{
for(inti=1;i<=4;i++)//3pos,filloperator
{
for(intj=1;j<=4;j++)
{
for(intk=1;k<=4;k++)
{
ints1=calc(i,in[1],in[2]);
ints2=calc(j,s1,in[3]);
ints3=calc(k,s2,in[4]);
if(s3==24)
{
if(in[1]>=in[2]&&s1>=in[3]&&s2>=in[4])
{
cout<<in[1]<<oper[i]<<in[2]<<'='<<s1<<endl;
cout<<s1<<oper[j]<<in[3]<<'='<<s2<<endl;
cout<<s2<<oper[k]<<in[4]<<'='<<s3<<endl;
return0;
}
}


s1=calc(j,in[2],in[3]);
s2=calc(i,in[1],s1);
s3=calc(k,s2,in[4]);
if(s3==24)
{
if(in[2]>=in[3]&&in[1]>=s1&&s2>=in[4])
{
cout<<in[2]<<oper[j]<<in[3]<<'='<<s1<<endl;
cout<<in[1]<<oper[i]<<s1<<'='<<s2<<endl;
cout<<s2<<oper[k]<<in[4]<<'='<<s3<<endl;
return0;
}
}


s1=calc(j,in[2],in[3]);
s2=calc(k,s1,in[4]);
s3=calc(i,in[1],s2);
if(s3==24)
{
if(in[2]>=in[3]&&s1>=in[4]&&in[1]>=s2)
{
cout<<in[2]<<oper[j]<<in[3]<<'='<<s1<<endl;
cout<<s1<<oper[k]<<in[4]<<'='<<s2<<endl;
cout<<in[1]<<oper[i]<<s2<<'='<<s3<<endl;
return0;
}
}


s1=calc(i,in[1],in[2]);
s2=calc(k,in[3],in[4]);
s3=calc(j,s1,s2);
if(s3==24)
{
if(in[1]>=in[2]&&in[3]>=in[4]&&s1>=s2)
{
cout<<in[1]<<oper[i]<<in[2]<<'='<<s1<<endl;
cout<<in[3]<<oper[k]<<in[4]<<'='<<s2<<endl;
cout<<s1<<oper[j]<<s2<<'='<<s3<<endl;
return0;
}
}


s1=calc(k,in[3],in[4]);
s2=calc(j,in[2],s1);
s3=calc(i,in[1],s2);
if(s3==24)
{
if(in[3]>=in[4]&&in[2]>=s1&&in[1]>=s2)
{
cout<<in[3]<<oper[k]<<in[4]<<'='<<s1<<endl;
cout<<in[2]<<oper[j]<<s1<<'='<<s2<<endl;
cout<<in[1]<<oper[i]<<s2<<'='<<s3<<endl;
return0;
}
}
}
}
}
}while(next_permutation(in+1,in+5));

cout<<"Noanswer!"<<endl;
return0;
}

Ⅳ 用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语言编程。要求 游戏给出4个1-13的整数 用户输入一个含这4个整数的四则运算表达式

输入:A 2 3 4 5 6 7 8 9 10 J Q K
输出:Yes/No
#include <stdio.h>
#include <string.h>

char t[10][10];
int b[5][1000],bx[3][200],by[3][200],g[5],p[5];
int i,j,k;
bool f;

int main()
{
while (~scanf("%s",&t[0]))
{
for (i=1;i<4;i++)
scanf("%s",&t[i]);
for (i=0;i<4;i++)
if (t[i][0]=='A')
g[i+1]=1;
else if (t[i][0]=='J')
g[i+1]=11;
else if (t[i][0]=='Q')
g[i+1]=12;
else if (t[i][0]=='K')
g[i+1]=13;
else if (t[i][0]=='1')
g[i+1]=10;
else
g[i+1]=t[i][0]-48;
memset(b,255,sizeof(b));
for (p[1]=1;p[1]<=4;p[1]++) if (b[4][24]!=4)
for (p[2]=1;p[2]<=4;p[2]++) if ((p[1]!=p[2]) && (b[4][24]!=4))
for (p[3]=1;p[3]<=4;p[3]++) if ((p[1]!=p[3]) && (p[2]!=p[3]) && (b[4][24]!=4))
{
p[4]=10-p[1]-p[2]-p[3];
memset(b,255,sizeof(b));
b[1][g[p[1]]]=1;
for (i=2;i<=4;i++)
for (j=500;j>0;j--)
if (b[i-1][j]==i-1)
{
b[i][j+g[p[i]]]=i;
if (j>g[p[i]])
b[i][j-g[p[i]]]=i;
if (j<g[p[i]])
b[i][g[p[i]]-j]=i;
if (j*g[p[i]]<1000)
b[i][j*g[p[i]]]=i;
if (j%g[p[i]]==0)
b[i][j/g[p[i]]]=i;
if ((j!=0) && (g[p[i]]%j==0))
b[i][g[p[i]]/j]=i;
}
if (b[4][24]!=4)
{
memset(bx,255,sizeof(bx));
memset(by,255,sizeof(by));
bx[1][g[p[1]]]=1;
bx[2][g[p[1]]+g[p[2]]]=2;
if (g[p[1]]>g[p[2]])
bx[2][g[p[1]]-g[p[2]]]=2;
if (g[p[1]]<g[p[2]])
bx[2][g[p[2]]-g[p[1]]]=2;
bx[2][g[p[1]]*g[p[2]]]=2;
if (g[p[1]]%g[p[2]]==0)
bx[2][g[p[1]]/g[p[2]]]=2;
if (g[p[2]]%g[p[1]]==0)
bx[2][g[p[2]]/g[p[1]]]=2;
by[1][g[p[3]]]=1;
by[2][g[p[3]]+g[p[4]]]=2;
if (g[p[3]]>g[p[4]])
by[2][g[p[3]]-g[p[4]]]=2;
if (g[p[3]]<g[p[4]])
by[2][g[p[4]]-g[p[3]]]=2;
by[2][g[p[3]]*g[p[4]]]=2;
if (g[p[3]]%g[p[4]]==0)
by[2][g[p[3]]/g[p[4]]]=2;
if (g[p[4]]%g[p[3]]==0)
by[2][g[p[4]]/g[p[3]]]=2;
for (i=200;i>0;i--)
if (bx[2][i]==2)
for (j=200;j>0;j--)
if (by[2][j]==2)
if ((i+j==24) || (i-j==24) || (j-i==24) || (i*j==24) || ((i%j==0) && (i/j==24) || ((j%i==0) && (j/i==24))))
{
b[4][24]=4;
break;
}
}
}
if (b[4][24]==4)
puts("Yes");
else
puts("No");
}
return 0;
}

阅读全文

与24点算法编程相关的资料

热点内容
oppor系列如何解除应用加密 浏览:599
程序员那么可爱姜逸城初恋 浏览:496
modbustcp编程 浏览:491
实况为什么安卓看不了 浏览:129
Java多线程Queue 浏览:95
云服务器499元三年 浏览:980
nbd源码 浏览:847
x86在arm上编译 浏览:8
linux怎么配置网络 浏览:307
程序员想要的小礼物 浏览:187
java获取网页url 浏览:625
怎么做解压神器泡泡版 浏览:967
自己动手做一个c编译器 浏览:930
手机如何链接谷歌服务器地址 浏览:137
废掉一个程序员的武功 浏览:249
java树形算法 浏览:642
通达信加锁指标源码怎么看 浏览:755
将同名文件移动到部分同名文件夹 浏览:404
摆荡指标加压力线源码 浏览:916
新一代单片机特征 浏览:770