展开全部
下面是我自己写的一个程序:
我的解法是把这个问题分解成了两个子问题,首先求出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 dupflag=false;
for(int j=0;j<idx;++j){if(sub[j]==i)dupflag=true;}
if(dupflag==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)
主程序为了简化,省去了对输入的检查,楼主可以自己添加。
我的解法是把这个问题分解成了两个子问题,首先求出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 dupflag=false;
for(int j=0;j<idx;++j){if(sub[j]==i)dupflag=true;}
if(dupflag==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)
主程序为了简化,省去了对输入的检查,楼主可以自己添加。
展开全部
1:你的函数非要用int
函数名()这样的吗?
2:试试重载fabs()这个,因为fabs默认参数是double型的,你传进去的是float型的,会有精度丢失。
3:这个24点真的很挫。。。。
函数名()这样的吗?
2:试试重载fabs()这个,因为fabs默认参数是double型的,你传进去的是float型的,会有精度丢失。
3:这个24点真的很挫。。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐于2016-01-01
展开全部
把随机生成的四个数放到数组里,判断加起来等于24就好;
参考代码如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define LING 1E-6
#define CONT 4
#define VOLUE 24
float number[CONT];
char expression[CONT][20] ;
bool m_judge = false; //判断是否有解。
int count = 0;
void Find(int n)
{
int i = 0, j = 0;
if (n == 1)
{
if ( fabs(number[0] - 24) <= LING)
{
for (i = 0; i < 20; i++)
{
printf("%c", expression[0][i]) ;
}
printf("\t\t") ;
m_judge = true;
count ++;
if((count % 2)==0) //使输出时每行三个表达式
printf("\n") ;
}
else
{ }
}
for(i = 0; i < n; i++) //查找
{
for (j = i + 1; j < n; j++) //与其后面的查找进行计算
{
float a, b;
char expressiona[20], expressionb[20];
a = number[i] ;
b = number[j] ;
number[j] = number[n - 1];
strcpy(expressiona, expression[i]) ;
strcpy(expressionb, expression[j]) ;
strcpy(expression[j], expression[n - 1]) ;
sprintf(expression[i], "(%s+%s)", expressiona, expressionb) ;
number[i] = a + b;
Find(n-1);
///////////////////////////////////
sprintf(expression[i], "(%s-%s)", expressiona, expressionb) ;
number[i] = a - b;
Find(n-1);
sprintf(expression[i], "(%s-%s)", expressionb, expressiona) ;
number[i] = b - a;
Find(n-1);
sprintf(expression[i], "(%s*%s)", expressiona, expressionb) ;
number[i] = a * b;
Find(n-1);
if (b != 0)
{
sprintf(expression[i], "(%s/%s)", expressiona, expressionb) ;
number[i] = a / b;
Find(n-1);
}
if (a != 0)
{
sprintf(expression[i], "(%s/%s)", expressionb, expressiona) ;
number[i] = b / a;
Find(n-1);
}
number[i] = a; // 最后一层的Find(2)调用完成后将a重新赋值给number[i]即number[0]
number[j] = b; // 最后一层的Find(2)调用完成后将b重新赋值给nubmer[j]即number[1]
strcpy(expression[i], expressiona) ;
strcpy(expression[j], expressionb) ;
}
}
}
int main()
{
int i, j ;
printf("请输入四个数:\n") ;
for (i = 0; i < CONT; i++)
{
char ch[20], s;
int a ;
printf("第%d个数:", i+1) ;
scanf("%f", &number[i]) ;
a = (int)number[i] ;
s = char(a + 48);
ch[0] = s ;
for (j = 1; j < 20; j++)
{
ch[j] = 0 ;
}
strcpy(expression[i], ch) ;
}
printf("\n") ;
Find(CONT) ;
if(m_judge==true)
{
printf("\n\n成功!\n") ;
printf("总共的计算方法共有:%d\n", count) ;
}
else
{
printf("失败!") ;
}
return 0;
}
参考代码如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define LING 1E-6
#define CONT 4
#define VOLUE 24
float number[CONT];
char expression[CONT][20] ;
bool m_judge = false; //判断是否有解。
int count = 0;
void Find(int n)
{
int i = 0, j = 0;
if (n == 1)
{
if ( fabs(number[0] - 24) <= LING)
{
for (i = 0; i < 20; i++)
{
printf("%c", expression[0][i]) ;
}
printf("\t\t") ;
m_judge = true;
count ++;
if((count % 2)==0) //使输出时每行三个表达式
printf("\n") ;
}
else
{ }
}
for(i = 0; i < n; i++) //查找
{
for (j = i + 1; j < n; j++) //与其后面的查找进行计算
{
float a, b;
char expressiona[20], expressionb[20];
a = number[i] ;
b = number[j] ;
number[j] = number[n - 1];
strcpy(expressiona, expression[i]) ;
strcpy(expressionb, expression[j]) ;
strcpy(expression[j], expression[n - 1]) ;
sprintf(expression[i], "(%s+%s)", expressiona, expressionb) ;
number[i] = a + b;
Find(n-1);
///////////////////////////////////
sprintf(expression[i], "(%s-%s)", expressiona, expressionb) ;
number[i] = a - b;
Find(n-1);
sprintf(expression[i], "(%s-%s)", expressionb, expressiona) ;
number[i] = b - a;
Find(n-1);
sprintf(expression[i], "(%s*%s)", expressiona, expressionb) ;
number[i] = a * b;
Find(n-1);
if (b != 0)
{
sprintf(expression[i], "(%s/%s)", expressiona, expressionb) ;
number[i] = a / b;
Find(n-1);
}
if (a != 0)
{
sprintf(expression[i], "(%s/%s)", expressionb, expressiona) ;
number[i] = b / a;
Find(n-1);
}
number[i] = a; // 最后一层的Find(2)调用完成后将a重新赋值给number[i]即number[0]
number[j] = b; // 最后一层的Find(2)调用完成后将b重新赋值给nubmer[j]即number[1]
strcpy(expression[i], expressiona) ;
strcpy(expression[j], expressionb) ;
}
}
}
int main()
{
int i, j ;
printf("请输入四个数:\n") ;
for (i = 0; i < CONT; i++)
{
char ch[20], s;
int a ;
printf("第%d个数:", i+1) ;
scanf("%f", &number[i]) ;
a = (int)number[i] ;
s = char(a + 48);
ch[0] = s ;
for (j = 1; j < 20; j++)
{
ch[j] = 0 ;
}
strcpy(expression[i], ch) ;
}
printf("\n") ;
Find(CONT) ;
if(m_judge==true)
{
printf("\n\n成功!\n") ;
printf("总共的计算方法共有:%d\n", count) ;
}
else
{
printf("失败!") ;
}
return 0;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
#include<stdio.h>
#define C case
double fun(double a1,double a2,int b)
{switch(b)
{C 0:return (a1+a2);
C 1:return (a1-a2);
C 2:return (a1*a2);
C 3:return (a1/a2);
}
}
void main()
{ int g;
for(g=0;g<100;)
{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]="+-*/";
printf("请输入4个数,数字与数字之间用空格隔开:");
for(i=0;i<4;i++)
{scanf("%lf",num+i); save[i]=num[i];}
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)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]);
}
}
}
}
}
g++;
}
}
#define C case
double fun(double a1,double a2,int b)
{switch(b)
{C 0:return (a1+a2);
C 1:return (a1-a2);
C 2:return (a1*a2);
C 3:return (a1/a2);
}
}
void main()
{ int g;
for(g=0;g<100;)
{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]="+-*/";
printf("请输入4个数,数字与数字之间用空格隔开:");
for(i=0;i<4;i++)
{scanf("%lf",num+i); save[i]=num[i];}
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)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]);
}
}
}
}
}
g++;
}
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询