写了个24点的程序,就是代码量太大了,大家帮忙压缩一下

prolovec 2009-05-25 10:06:45
//算法思想:将数,括号,运算符的情况分别列出来,再进行计算
#include<iostream>
using namespace std;
int m,n;//记录最终结果
int locate;//辅助定位
bool kk,mark[17];//记录数或运算符使用情况
char last[18]="((@#((@)#(@))#@))";//记录所有可能的情况:@代表数#代表运算符
float h_data[24][4],d[4],da[4];//记录数据的可能全排列
char h_symbol[64][3],s[4],sy[4]={'+','-','*','/'};//记录运算符的可能全排列
void deal_data(int n);//求数的无重复全排列
void deal_symbol(int number);//求运算符的可重复全排列
void compute(int n);//括号共有五种结构,函数求出第n种结构的结果
void print(int n);//输出结果
void inti(int a,char c,bool kk);//函数用于求出m和a的某种运算结果
void extra(int a,int b);//处理特殊情况
int main()
{
bool key;
int i,j,k,l;

while(1)
{

memset(mark,false,sizeof(mark));
key=true;
for(i=0;i<4;i++)
cin>>da[i];
if(da[0]==0)break;
locate=0;
deal_data(0);
locate=0;
deal_symbol(0);
for(i=0;key&&i<24;i++)
for(j=0;key&&j<64;j++)
for(k=1;key&&k<6;k++)
{
m=n=1;
for(l=0;l<4;l++)
d[l]=h_data[i][l];
for(l=0;l<3;l++)
s[l]=h_symbol[j][l];
compute(k);
if(n==0)n=1;
if(m%n)continue;
else if(m/n!=24)continue;
else{
print(k);
key=false;
}
}
if(key)cout<<"it is impossible!"<<endl;
}
return 0;
}
void deal_data(int n)
{
int i;
if(n==4)
{
for(i=0;i<4;i++)
h_data[locate][i]=d[i];
locate++;
}
else
{
for(i=0;i<4;i++)
{
if(mark[i]==false)
{
d[n]=da[i];
mark[i]=true;
deal_data(n+1);
mark[i]=false;
}
}
}
}
void deal_symbol(int number)
{
int i;
if(number==3)
{
for(i=0;i<3;i++)
h_symbol[locate][i]=s[i];
locate++;
}
else
{
for(i=0;i<4;i++)
{
s[number]=sy[i];
deal_symbol(number+1);
}
}
}
void inti(int a,char c,bool kk)
{
int h;
if(kk)
{
switch (c)
{
case '+':m=a*n+m;break;
case '-':m=m-a*n;break;
case '*':m=a*m;break;
case '/':if(a==0){a=5000;}else if(m%a){n*=a;}else{m=m/a;};break;
default:break;
}
}
else
{
switch (c)
{
case '+':m=a*n+m;break;
case '-':m=a*n-m;break;
case '*':m=a*m;break;
case '/':if(m==0){m=5000;}else if((a*n)%m){h=m;m=a*n;n=h;}else{m=a*n/m;n=1;};break;
default:break;
}
}
}
void compute(int n)
{
switch(n)
{
case 1:m=d[0];inti(d[1],s[0],1);inti(d[2],s[1],1);inti(d[3],s[2],1);break;
case 2:m=d[1];inti(d[2],s[1],1);inti(d[0],s[0],0);inti(d[3],s[2],1);break;
case 3:m=d[0];inti(d[1],s[0],1);extra(d[2],d[3]);break;
case 4:m=d[1];inti(d[2],s[1],1);inti(d[3],s[2],1);inti(d[0],s[0],0);break;
case 5:m=d[2];inti(d[3],s[2],1);inti(d[1],s[1],0);inti(d[0],s[0],0);break;
default:break;
}
}
void print(int n)
{
memset(mark,true,sizeof(mark));
int point=0;
int i=0,j=0;
switch(n)
{
case 1:mark[4]=mark[5]=mark[9]=mark[12]=mark[15]=mark[16]=false;break;
case 2:mark[0]=mark[4]=mark[7]=mark[9]=mark[15]=mark[16]=false;break;
case 3:mark[0]=mark[4]=mark[5]=mark[11]=mark[12]=mark[16]=false;break;
case 4:mark[0]=mark[1]=mark[7]=mark[9]=mark[12]=mark[16]=false;break;
case 5:mark[0]=mark[1]=mark[4]=mark[7]=mark[11]=mark[12]=false;break;
default:break;
}
for(point=0;point<17;point++)
{
switch(point)
{
case 0:
case 1:
case 4:
case 5:
case 7:
case 9:
case 11:
case 12:

case 15:
case 16:if(mark[point])cout<<last[point];continue;
case 2:
case 6:

case 10:
case 14:cout<<d[i++];continue;
case 3:
case 8:
case 13:cout<<s[j++];continue;
default:continue;
}
}
cout<<endl;
}
void extra(int a,int b)
{
int p,q,r;
switch (s[2])
{
case '+':p=a+b;q=1;break;
case '-':p=a-b;q=1;break;
case '*':p=a*b;q=1;break;
case '/':p=a;q=b;break;
default:break;
}
switch (s[1])
{
case '+':r=m*q+n*p;n=n*q;m=r;break;
case '-':r=m*q-n*p;n=n*q;m=r;break;
case '*':m=m*p;n=n*q;break;
case '/':m=m*q;n=n*p;break;
default:break;
}
}
...全文
168 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
aqqaww 2009-05-26
  • 打赏
  • 举报
回复
学习学习
aqqaww 2009-05-26
  • 打赏
  • 举报
回复
学习
果菲 2009-05-26
  • 打赏
  • 举报
回复
学习!!!
prolovec 2009-05-26
  • 打赏
  • 举报
回复
//输出那块处理了下,感觉还是有点多。。。。
//算法思想:将数,括号,运算符的情况分别列出来,再进行计算
#include<iostream>
using namespace std;
int m,n;//记录最终结果
int locate;//辅助定位
bool kk,mark[17];//记录数或运算符使用情况
float h_data[24][4],d[4],da[4];//记录数据的可能全排列
char h_symbol[64][3],s[4],sy[4]={'+','-','*','/'};//记录运算符的可能全排列
void deal_data(int n);//求数的无重复全排列
void deal_symbol(int number);//求运算符的可重复全排列
void compute(int n);//括号共有五种结构,函数求出第n种结构的结果
void print(int n);//输出结果
void inti(int a,char c,bool kk);//函数用于求出m和a的某种运算结果
void extra(int a,int b);//处理特殊情况
int main()
{
bool key;
int i,j,k,l;

while(1)
{

memset(mark,false,sizeof(mark));
key=true;
for(i=0;i<4;i++)
cin>>da[i];
if(da[0]==0)break;
locate=0;
deal_data(0);
locate=0;
deal_symbol(0);
for(i=0;key&&i<24;i++)
for(j=0;key&&j<64;j++)
for(k=1;key&&k<6;k++)
{
m=n=1;
for(l=0;l<4;l++)
d[l]=h_data[i][l];
for(l=0;l<3;l++)
s[l]=h_symbol[j][l];
compute(k);
if(n==0)n=1;
if(m%n)continue;
else if(m/n!=24)continue;
else{
print(k);
key=false;
}

}
if(key)cout<<"it is impossible!"<<endl;
}
return 0;
}
void deal_data(int n)
{
int i;
if(n==4)
{
for(i=0;i<4;i++)
h_data[locate][i]=d[i];
locate++;
}
else
{
for(i=0;i<4;i++)
{
if(mark[i]==false)
{
d[n]=da[i];
mark[i]=true;
deal_data(n+1);
mark[i]=false;
}
}
}
}
void deal_symbol(int number)
{
int i;
if(number==3)
{
for(i=0;i<3;i++)
h_symbol[locate][i]=s[i];
locate++;
}
else
{
for(i=0;i<4;i++)
{
s[number]=sy[i];
deal_symbol(number+1);
}
}
}
void inti(int a,char c,bool kk)
{
int h;
if(kk)
{
switch (c)
{
case '+':m=a*n+m;break;
case '-':m=m-a*n;break;
case '*':m=a*m;break;
case '/':if(a==0){a=5000;}else if(m%a){n*=a;}else{m=m/a;};break;
default:break;
}
}
else
{
switch (c)
{
case '+':m=a*n+m;break;
case '-':m=a*n-m;break;
case '*':m=a*m;break;
case '/':if(m==0){m=5000;}else if((a*n)%m){h=m;m=a*n;n=h;}else{m=a*n/m;n=1;};break;
default:break;
}
}
}
void compute(int n)
{
switch(n)
{
case 1:m=d[0];inti(d[1],s[0],1);inti(d[2],s[1],1);inti(d[3],s[2],1);break;
case 2:m=d[1];inti(d[2],s[1],1);inti(d[0],s[0],0);inti(d[3],s[2],1);break;
case 3:m=d[0];inti(d[1],s[0],1);extra(d[2],d[3]);break;
case 4:m=d[1];inti(d[2],s[1],1);inti(d[3],s[2],1);inti(d[0],s[0],0);break;
case 5:m=d[2];inti(d[3],s[2],1);inti(d[1],s[1],0);inti(d[0],s[0],0);break;
default:break;
}
}
void print(int n)
{

int i=0,j=0;
switch(n)
{
case 1:cout<<"(("<<d[0]<<s[0]<<d[1]<<")"<<s[1]<<d[2]<<")"<<s[2]<<d[3]<<endl;break;
case 2:cout<<"("<<d[0]<<s[0]<<"("<<d[1]<<s[1]<<d[2]<<"))"<<s[2]<<d[3]<<endl;break;
case 3:cout<<"("<<d[0]<<s[0]<<d[1]<<")"<<s[1]<<"("<<d[2]<<s[2]<<d[3]<<")"<<endl;break;
case 4:cout<<d[0]<<s[0]<<"(("<<d[1]<<s[1]<<d[2]<<")"<<s[2]<<d[3]<<")"<<endl;break;
case 5:cout<<d[0]<<s[0]<<"("<<d[1]<<s[1]<<"("<<d[2]<<s[2]<<d[3]<<"))"<<endl;break;
default:break;
}
}
void extra(int a,int b)
{
int p,q,r;
switch (s[2])
{
case '+':p=a+b;q=1;break;
case '-':p=a-b;q=1;break;
case '*':p=a*b;q=1;break;
case '/':p=a;q=b;break;
default:break;
}
switch (s[1])
{
case '+':r=m*q+n*p;n=n*q;m=r;break;
case '-':r=m*q-n*p;n=n*q;m=r;break;
case '*':m=m*p;n=n*q;break;
case '/':m=m*q;n=n*p;break;
default:break;
}
}
nanjingling88 2009-05-26
  • 打赏
  • 举报
回复
dddddddddddddd
光宇广贞 2009-05-26
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 prolovec 的回复:]
晕哦,输出那块可以优化掉一大堆的。。。。。
[/Quote]

好深的循环啊!要压缩的不止是代码行数了……
prolovec 2009-05-25
  • 打赏
  • 举报
回复
晕哦,输出那块可以优化掉一大堆的。。。。。
lingyin55 2009-05-25
  • 打赏
  • 举报
回复
转一个,参考下
http://blog.sina.com.cn/s/blog_4e811cd401000c1r.html


#include <string>
#include <cmath>

using namespace std;

const double PRECISION = 1E-6;
const int COUNT_OF_NUMBER = 4;
const int NUMBER_TO_BE_CAL = 24;

double number[COUNT_OF_NUMBER];
string expression[COUNT_OF_NUMBER];

bool Search(int n)
{
if (n == 1) {
if ( fabs(number[0] - NUMBER_TO_BE_CAL) < PRECISION ) {
cout << expression[0] << endl;
return true;
} else {
return false;
}
}

for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
double a, b;
string expa, expb;

a = number[i];
b = number[j];
number[j] = number[n - 1];

expa = expression[i];
expb = expression[j];
expression[j] = expression[n - 1];

expression[i] = '(' + expa + '+' + expb + ')';
number[i] = a + b;
if ( Search(n - 1) ) return true;

expression[i] = '(' + expa + '-' + expb + ')';
number[i] = a - b;
if ( Search(n - 1) ) return true;

expression[i] = '(' + expb + '-' + expa + ')';
number[i] = b - a;
if ( Search(n - 1) ) return true;


expression[i] = '(' + expa + '*' + expb + ')';
number[i] = a * b;
if ( Search(n - 1) ) return true;

if (b != 0) {
expression[i] = '(' + expa + '/' + expb + ')';
number[i] = a / b;
if ( Search(n - 1) ) return true;
}
if (a != 0) {
expression[i] = '(' + expb + '/' + expa + ')';
number[i] = b / a;
if ( Search(n - 1) ) return true;
}

number[i] = a;
number[j] = b;
expression[i] = expa;
expression[j] = expb;
}
}
return false;
}

void main()
{
for (int i = 0; i < COUNT_OF_NUMBER; i++) {
char buffer[20];
int x;
cin >> x;
number[i] = x;
itoa(x, buffer, 10);
expression[i] = buffer;
}

if ( Search(COUNT_OF_NUMBER) ) {
cout << "Success." << endl;
} else {
cout << "Fail." << endl;
}
}
cyldf 2009-05-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hikaliv 的回复:]
引用 4 楼 tangshuiling 的回复:
先看看,建议加点注释,要人家评判也得让人看着没那么累才好!


你的钱好多啊……先散一万吧……我要五千……
[/Quote]
hikaliv 是抢劫犯,哈哈
ltc_mouse 2009-05-25
  • 打赏
  • 举报
回复
只要结果是正确的,时间,空间复杂度又符合要求,多几行代码没关系的~

这个网页上提供了几种算法和源码,lz可以参考参考
http://www.kedou.cn/Product/Easy24/refrence.htm
damo_xu 2009-05-25
  • 打赏
  • 举报
回复
这是我用递归写的,要不是考虑输出,代码要减一半,而且可以算任意几个数(即不限4个)
PS:有个牛人用逆波兰写的,很牛。楼主可试试。
#define N 4
int z=0,k1=0,k2=0;
vector<double> Operand(4);
vector<int> Operator(3);

void print(const vector<int>& v)
{ copy(v.begin(),v.end(),ostream_iterator<int>(cout," ")); }

void print_op(int i)
{
switch (i)
{
case 0 : cout<<" + "; break;
case 1 : cout<<" - "; break;
case 2 : cout<<" * "; break;
case 3 : cout<<" / "; break;
case 4 : cout<<" - "; break;
case 5 : cout<<" / "; break;
}
}

void print(vector<double> A,vector<int> op,int i)
{
if (i==4||i==5||i==6||i==7) { swap(A[0],A[1]); i=i-4; }

switch (i)
{
case 0 : cout<<"(("<<A[0]; print_op(op[0]); cout<<A[1]<<')';
print_op(op[1]); cout<<A[2]<<')';
print_op(op[2]); cout<<A[3]; break;
// ((A#B||B#A)#C)#D

case 1 : cout<<A[3]; print_op(op[2]);
cout<<"(("<<A[0]; print_op(op[0]); cout<<A[1]<<')';
print_op(op[1]); cout<<A[2]<<')'; break;
// D#((A#B||B#A)#C)

case 2 : cout<<'('<<A[2]; print_op(op[1]);
cout<<'('<<A[0]; print_op(op[0]); cout<<A[1]<<"))";
print_op(op[2]); cout<<A[3]; break;
// (C#(A#B||B#A))#D

case 3 : cout<<A[3]; print_op(op[2]);
cout<<'('<<A[2]; print_op(op[1]);
cout<<'('<<A[0]; print_op(op[0]); cout<<A[1]<<"))"; break;
// D#(C#(A#B||B#A))
}
}

void PRINT(vector<double> A,vector<int> op,int i)
{
if (i==4||i==5||i==6||i==7) swap(A[0],A[1]);
if (i==2||i==3||i==6||i==7) swap(A[2],A[3]);

if (i%2==0)
{
cout<<'('<<A[0]; print_op(op[0]); cout<<A[1]<<')';
print_op(op[2]);
cout<<'('<<A[2]; print_op(op[1]); cout<<A[3]<<')';
// (A#B||B#A)#(C#D||D#C)
}
else
{
cout<<'('<<A[2]; print_op(op[1]); cout<<A[3]<<')';
print_op(op[2]);
cout<<'('<<A[0]; print_op(op[0]); cout<<A[1]<<')';
// (C#D||D#C)#(A#B||B#A)
}
}

inline double operation(const double x,const double y,int i)
{
double res;
switch (i)
{
case 0 : res = x + y; break;
case 1 : res = x - y; break;
case 2 : res = x * y; break;
case 3 : res = x / y; break;
case 4 : res = y - x; break;
case 5 : res = y / x; break;
}
return res;
}

void rechnen(vector<double> a,int n)
{
if (n==2) // Rekursion beendet
{
for (int i=0;i<6;i++)
{
if (operation(a[0],a[1],i)==24.0)
{
z++;
int k3=0; if (i>3) k3++;
Operator[2]=i;
print(Operand,Operator,k1+k2+k3); cout<<endl;
break; // z.B. a+b=24, a#b(b#a)!=24
}
}
}
else
{
vector<double> b(n-1);
for (int u=0;u<n;u++)
{
for (int v=u+1;v<n;v++)
{
if (n==4) { Operand[0]=a[u]; Operand[1]=a[v]; }
if (n==3) { Operand[2]=a[v-u]; Operand[3]=a[3-v+u]; }
// A, B, C, D sind gelesen
for (int i=0,j=1;j<n-1;i++)
{ if (i!=u&&i!=v) b[j++]=a[i]; }
// "n=4" b[1],b[2]
// "n=3" b[1]
for (int i=0;i<6;i++)
{
Operator[4-n]=i;
// op[0], op[1] sind gelesen
b[0]=operation(a[u],a[v],i);

if (i>3) { if (n==4) k1=4; if (n==3) k2=2; }
if (n==3&&u==1) // (a#b)#(c#d)
{
for (int i=0;i<6;i++)
{
if (operation(b[1],b[0],i)==24.0)
{
z++;
int k3=0; if (i>3) k3++;
Operator[2]=i;
PRINT(Operand,Operator,k1+k2+k3);
cout<<endl; break;
}
}
}
else rechnen(b,n-1);
k2=0;
if (n==4) k1=0;
}
}
}
}
}

int main()
{
while (1)
{
double f; vector<double> a(N);
cout<<"geb bitte "<<N<<" Zahlen ein:"<<endl;
for (int i=0;i<N&&cin>>f;i++) a[i]=f;
// for (int i=0;i<4;i++) cout<<a[i]<<' ';
rechnen(a,N);
cout<<"\nAlso gibt es "<<z<<" Moeglichkeiten.\n\n";
}
return 0;
}

kingstarer 2009-05-25
  • 打赏
  • 举报
回复
别人写的24点,好像比你的短,可参考


#include<stdio.h>
double fun(double a1,double a2,int 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]="+-*/";
printf("input 4 numbers:");
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]);
}
}
}
}
}
}

光宇广贞 2009-05-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tangshuiling 的回复:]
先看看,建议加点注释,要人家评判也得让人看着没那么累才好!
[/Quote]

你的钱好多啊……先散一万吧……我要五千……
tangshuiling 2009-05-25
  • 打赏
  • 举报
回复
先看看,建议加点注释,要人家评判也得让人看着没那么累才好!
光宇广贞 2009-05-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hairetz 的回复:]
看看先。
感觉还不错啊,deal_data这种全排列,递归得蛮精简了啊。
只是不知道你测试正确不。
[/Quote]

我的算法是正确的,哈哈……保证。
  • 打赏
  • 举报
回复
看看先。
感觉还不错啊,deal_data这种全排列,递归得蛮精简了啊。
只是不知道你测试正确不。
光宇广贞 2009-05-25
  • 打赏
  • 举报
回复
复杂度如何?

你计算一个这个,输入七个数,然后给出所有无算律冗余的结果集来……这是我的算法的极限,CPU 2.4,内存2G,1分后,内存废。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧