广州刘关张集团好不好:请问用C语言怎么算24 尽量给我原代码 谢谢啊!!

来源:百度文库 编辑:高考问答 时间:2024/05/05 15:10:49

主要是使用逆波兰表达式的求值。欢迎测试和指正!

[code]
/* cal24.c
* given N integer numbers
* find one expression which produces value T using all
* the N numbers and {+,-,*,/} operators
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 4 /* number of cards */
#define T 24 /* target solution */
#define M 13 /* maximum card value */
#define STACK_SIZE (N+N-1)
#define EPS 1e-6
#define ADD M+1
#define SUB M+2
#define MUL M+3
#define DIV M+4

/* evaluate an expression in reverse Polish notation (RPN) */
double eval(int expr[])
{
double oprnds[N],oprnd1,oprnd2;
int top = -1,i,op;
for(i = 0;i<STACK_SIZE;++i){
op = expr[i];
if(op<=M){
oprnds[++top] = (double)op;
continue;
}
oprnd1 = oprnds[top--];
oprnd2 = oprnds[top--];
switch(op){
case ADD: oprnd1 += oprnd2; break;
case SUB: oprnd1 -= oprnd2; break;
case MUL: oprnd1 *= oprnd2; break;
case DIV:
if(oprnd2<EPS && oprnd2>-EPS) return 0.0;
oprnd1 /= oprnd2;
}
oprnds[++top] = oprnd1;
}
return oprnds[top];
}

int succ(int expr[])
{
double x = eval(expr);
if(x>T-EPS && x<T+EPS) return 1;
return 0;
}

/* just to make the expression more readable by human */
void printsolution(int expr[])
{
double oprnds[N],oprnd1,oprnd2,result;
int top = -1,i,op;
char c;
for(i = 0;i<STACK_SIZE;++i){
op = expr[i];
if(op<=M){
oprnds[++top] = (double)op;
continue;
}
oprnd1 = oprnds[top--];
oprnd2 = oprnds[top--];
switch(op){
case ADD:
c = '+';
result = oprnd1 + oprnd2;
break;
case SUB:
c = '-';
result = oprnd1 - oprnd2;
break;
case MUL:
c = '*';
result = oprnd1 * oprnd2;
break;
case DIV:
c = '/';
result = oprnd1 / oprnd2;
}
printf("%.2f %c %.2f => %.2f\n",oprnd1,c,oprnd2,result);
oprnds[++top] = result;
}
}

/* update ret[] with next possible permutation of N cards */
int permute(int ret[])
{
int orig[N],i,j = 1;
for(i = 0;i<N-1;++i)
if(ret[i]<ret[i+1]){
j = 0;
break;
}
if(j) return 0;
for(i = 0;i<N;++i) orig[i] = ret[i];
for(i = N-2;i>=0;--i)
if(orig[i]<orig[i+1]) break;
for(j = N-1;j>i;--j)
if(orig[j]>orig[i]) break;
ret[i] = orig[j];
orig[j] = orig[i];
for(j = i+1;j<N;++j)
ret[j] = orig[N-j+i];
return 1;
}

/* update ops[] with next possible operators */
int operators(int ops[])
{
int i,j;
for(i = N-1;i>=0;--i){
if(ops[i]<DIV){
++ops[i];
for(j = i+1;j<N-1;++j) ops[j] = ADD;
return 1;
}
}
return 0;
}

/* update expr[] with next possible expression in RPN */
int expressions(int expr[])
{
if(expr[3]>M && expr[4]>M) return 0;
if(expr[2]>M && expr[4]>M) expr[2]^=expr[3]^=expr[2]^=expr[3];
else if(expr[2]>M) expr[4]^=expr[5]^=expr[4]^=expr[5];
else if(expr[3]>M) expr[2]^=expr[3]^=expr[2]^=expr[3];
else expr[3]^=expr[4]^=expr[3]^=expr[4];
return 1;
}

int main(int argc,char *argv[])
{
int opd[N],pmt[N],ops[N-1],expr[STACK_SIZE],i,succeed = 1;
if(argc<N+1) exit(printf("Not enough arguments!\n"));
for(i = 0;i<N;++i) opd[i] = atoi(argv[i+1]);
for(i = 0;i<N;++i) pmt[i] = i;
for(i = 0;i<N-1;++i) ops[i] = ADD;
while(1){
for(i = 0;i<N;++i) expr[i] = opd[pmt[i]];
for(i = 0;i<N-1;++i) expr[N+i] = ops[i];
if(succ(expr)) break;
while(expressions(expr))
if(succ(expr)) break;
if(succ(expr)) break;
if(!operators(ops)){
if(!permute(pmt)){
succeed = 0;
break;
}
for(i = 0;i<N-1;++i) ops[i] = ADD;
}
}
if(!succeed) exit(printf("Find no solutions!\n"));
printsolution(expr);
}

===========================================这里还有一个!TC版
/*在TC2.0下通过,基本实现了24点算法*/
#include<stdio.h>
#include <conio.h>
int enumerate(int ans);

char op[]={'+','-','*','/'};
char *model[]=
{
"((AxB)yC)zD",
"(Ay(BxC))zD",
"Az(By(CxD))",
"Az((BxC)yD)",
"(AxB)z(CyD)"
};
int *A, *B, *C, *D;
char *x, *y ,*z;
int ***opd;
char ***opr;
char *sample;
int **oprand[]={&A,&B,&C,&D};
char **oprator[]={&x,&y,&z};
int a[4];
int main(void)
{
int i;
printf("Enter %d numbers.\n",4);
for(i=0;i<sizeof a/sizeof a[0];i++)
scanf("%d",a+i);
if(enumerate(24)==0)
printf("No solution!\n");
return 0;
}
int calculate()
{
int v1,v2;
char op;
if(*sample=='A'||*sample=='B'||*sample=='C'||*sample=='D')
v1=***opd++;
else if(*sample=='('){
sample++;
v1=calculate();
}
sample++;
while(*sample=='x'||*sample=='y'||*sample=='z'){
op=***opr++;
sample++;
if(*sample=='A'||*sample=='B'||*sample=='C'||*sample=='D')
v2=***opd++;
else if(*sample=='('){
sample++;
v2=calculate();
}
sample++;
//clrscr();
switch(op)
{
case '+': v1+=v2; break;
case '-' : if(v1<v2) return -1000;
else v1-=v2;break;
case '*': v1*=v2; break;
case '/': if(v2==0||v1%v2!=0)
return -1000;
else v1/=v2; break;
}
}
return v1;
}
int enumerate(int ans)
{
int k;
for(A=a;A<a+4;A++)
for(B=a;B<a+4;B++){
if(B==A) continue;
for(C=a;C<a+4;C++){
if(C==A||C==B)
continue;
D=a+6-(A-a)-(B-a)-(C-a);
for(x=op;x<op+4;x++)
for(y=op;y<op+4;y++)
for(z=op;z<op+4;z++)
for(k=0;k<5;k++){
opd=oprand;
opr=oprator;
sample=model[k];
if(calculate()==ans)
{
opd=oprand;
opr=oprator;
sample=model[k];
while(*sample){
switch(*sample)
{
case 'A':
case 'B':
case 'C':
case 'D':printf("%d",***opd++); break;
case 'x':
case 'y':
case 'z':printf("%c",***opr++);break;
case '(':
case ')':printf("%c",*sample);break;
}
*sample++;
}
printf("=24\n\n");
return 1;
}
}
}
}
return 0;
}