计算24点的程序讨论,欢迎大家进来
http://club.it.sohu.com/read_art_sub.new.php?b=program&a=73842&sr=0&allchildnum=1&t=0&NoCache=1
欢迎大家发表看法,谢谢帮顶,会给分的
[解决办法]
4个数算24不难,难在2处
1:去除所有重复,简单点是只去满足交换律的,复杂点要去除满足运算符翻转的。
2:推广到N个数算X
[解决办法]
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef float (*PF)(float, float);
char *ch[]={NULL, "A ", "2 ", "3 ", "4 ", "5 ", "6 ", "7 ", "8 ", "9 ", "10 ", "J ", "Q ", "K "};
char cc[]= "+-*/ ";
//int rand_seed = 0;
void rand_num(int *num)
{
int i;
// srand(num[(rand_seed++)%4]);
for(i=0; i <4; i++)
num[i] = rand()%12 +1;
}
float add(float x, float y)
{
return x+y;
}
float sub(float x, float y)
{
return x-y;
}
float mul(float x, float y)
{
return x*y;
}
float divide(float x, float y)
{
if((y> -0.0000001)&&(y <0.0000001))
return 0;
else return x/y;
}
/*The compute function!*/
void compute_24(int num[])
{
PF pf[4]={add,sub,mul,divide};
int i,j,k,x,y,z,t;
int flag=0,flag_i=0, flag_j=0, flag_equ_end2=0;
float op_x, op_y, op_z;
/*Kind 1*/
for(i=0; i <4; i++) /*num[i] is the first para*/
{
for(t=0; t <i; t++)
if(num[t] == num[i])
flag_i = 1;
if(flag_i)
{
flag_i=0;
continue;
}
for(j=0; j <4; j++) /*num[j] is the 2nd para*/
{
if(j == i)
continue;
for(t=j-1; t> 0; t--)
if((num[j] == num[t])&&(num[i]!=num[t]))
flag_j = 1;
if(flag_j)
{
flag_j=0;
continue;
}
for(x=0; x <4; x++) /*pf[x] is the 1st operation*/
{
if((j <i)&&
((x==0)||(x==2))
)
continue;
op_x = pf[x]((float)num[i],(float)num[j]);
for(k=0; k <4; k++) /*num[k] is the 3rd para, and the last is num[6-i-j-k]*/
{
if(k==i || k==j)
continue;
if(num[k] == num[6-i-j-k])
flag_equ_end2 = 1;
for(y=0; y <4; y++) /*pf[y] is the 2nd operation*/
{
if( (k <j)&&
(((x <2)&&(y <2)) ||
((x> 1)&&(y> 1)))
)
continue;
op_y = pf[y](op_x, (float)num[k]);
for(z=0; z <4; z++) /*pf[z] is the 3rd operation*/
{
if((x==y)&&(x==z)&&((i!=0)||(j!=1)||(k!=2)))
continue;
if( (((z <2)&&(y <2)) ||
((z> 1)&&(y> 1))) &&
(k> (6-i-j-k))
)
continue;
op_z = pf[z](op_y, (float)num[6-i-j-k]);
if(((op_z - 24)> -0.0000001) && ((op_z - 24) <0.0000001))
{
flag=1;
printf( "((%d %c %d) %c %d) %c %d == 24\n ",num[i], cc[x], num[j], cc[y], num[k], cc[z], num[6-i-j-k]);
}
}
}
if(flag_equ_end2)
{
flag_equ_end2 = 0;
break;
}
}
}
}
}
/*Kind 2*/
for(i=0; i <4; i++) /*num[i] is the first para*/
{
for(t=0; t <i; t++)
if(num[t] == num[i])
flag_i = 1;
if(flag_i)
{
flag_i=0;
continue;
}
for(j=0; j <4; j++) /*num[j] is the 2nd para*/
{
if(j == i)
continue;
for(t=j-1; t> -1; t--)
if((num[j] == num[t])&&(num[i]!=num[t]))
flag_j = 1;
if(flag_j)
{
flag_j=0;
continue;
}
for(x=0; x <2; x++) /*pf[x] is the 1st operation*/
{
if((j <i)&&(x==0))
continue;
op_x = pf[x]((float)num[i],(float)num[j]);
for(k=0; k <4; k++) /*num[k] is the 3rd para, and the last is num[6-i-j-k]*/
{
if(k==i || k==j)
continue;
for(y=0; y <2; y++) /*pf[y] is the 2nd operation*/
{
if((y==0)&&(k> (6-i-j-k)))
continue;
op_y = pf[y]((float)num[k],(float)num[6-i-j-k]);
for(z=2; z <4; z++) /*pf[z] is the 3rd operation*/
{
if((z==2) &&
(((k <i)&&(k <j)) ||
(((6-i-j-k) <i)&&((6-i-j-k) <j))
)
)
continue;
op_z = pf[z](op_x, op_y);
if(((op_z - 24)> -0.0000001) && ((op_z - 24) <0.0000001))
{
flag=1;
printf( "(%d %c %d) %c (%d %c %d) == 24\n ",num[i], cc[x], num[j], cc[z], num[k], cc[y], num[6-i-j-k]);
}
}
}
}
}
}
}
if(!flag)
{
flag = 0;
puts( "Sorry, there is no answer!! ");
}
}
int main()
{
int num[4],i;
char c= 'y ';
while(c == 'y ')
{
rand_num(num);
for(i=0; i <4; i++)
printf( "%d--%s\t ",num[i],ch[num[i]]);
puts( " ");
compute_24(num);
printf( "\n\nEnter 'y ' continue or others break: ");
scanf( "%c ",&c);
fflush(stdin);
}
}
[解决办法]
自己写的一个古老程序。
分两类情况:
1 (a op b)op(c op d) abcd为四个操作数, op 为四中运算之一
2 ((a op b) op c) op d
使用分类+循环即可,
重复性判断可能比较复杂了点,
仅供参考 ....
[解决办法]
JF啊JF
[解决办法]
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int N = 10;
int a[4] = {2,5,8,9};
char y[3];
int func(int i, int rslt)
{
int b = 0;
if(i==3)
{
if(rslt==a[3])
{
return 1;
}
else
{
return 0;
}
}
if(rslt%a[i]==0)
{
b=func(i+1, rslt/a[i]);
if(b!=NULL)
{
y[i]= '* ';
return b;
}
}
b=func(i+1, rslt-a[i]);
if(b)
{
y[i]= '+ ';
return b;
}
b=func(i+1, rslt+a[i]);
if(b)
{
y[i]= '- ';
return b;
}
b=func(i+1, rslt*a[i]);
if(b)
{
y[i]= '/ ';
return b;
}
return NULL;
}
int main(int argc, char *argv[])
{
func(0, 24);
for(int i=0; i <3; i++)
{
cout < <y[i] < < " ";
}
cout < <endl;
system( "PAUSE ");
return 0;
}
[解决办法]
写错了,不好意思!
[解决办法]
我自己前段时间也在看这个,方法就是穷举,自己比较喜欢的一种实现方法是这样的:
(1)4个数字排序,24种排法.
(2)计算过程两种:((1OP2)OP(3OP4))或者(((1OP2)OP3)OP4).
(3)任意两个数的可能的6个结果:A+B,A-B,A*B,A/B,B-A,B/A.
个人愚见,仅供参考~
[解决办法]
(2)计算过程两种:((1OP2)OP(3OP4))或者(((1OP2)OP3)OP4).
这是不够的。用什么逆波兰序表示法或者完全2叉树生成,应该是5种。
[解决办法]
我一直想寻求一个史上最牛的算24的程序,可惜一直找不到
所谓最牛,要至少符合下面一点:
1. 奇思妙想,从没人想过用这种方式来计算24
2. 程序效率奇高,可以证明是最快的算24程序
3. 程序简短无比,再也找不到比它还短的算24程序
4. 程序莫名其妙,很难看懂这个程序是什么意思,但是它确实能算出24
[解决办法]
看我一个php写的代码:http://blog.csdn.net/mathe/archive/2006/08/29/1135691.aspx
[解决办法]
有难度,不容易呀 !
[解决办法]
好强啊,我也研究一下看看