一个有难度的问题,高分征解 --- 关于求 N个数 用+ - * / 计算 K 的问题,up 有分,参与有奖

LLnju 2002-01-28 09:36:17
加精
这100分是给 up,gz 的人的,回答问题后我会重新开贴子给分的,分不够了我会加的,大家可以看看我以前的贴子,还没有不结账的,10G素数求解时我一共给出去了1K多分。

################### 目标 ##################
求解 N 个数( 1 - 9 ) 经过 + - * / 运算获得 K 的算法
( 在 N = 4 , K = 24 下就是 24 点 算法 )
要求求解出全部的 解( 对同一组数据只需求出一组解 )

**** 初步考虑 N <= 10. ****


################## 高分求解方案的初步设想 #####################
对每个 N ( 5 <= N <= 10 )设立一个大奖( Kaye(菜菜狗)呢,这个可要靠你的大力赞助,
我的可用分只有 1450 分了,上次看到你好像有 6K多分 ), 每三天发一次奖,愿意一起主办的请与我联系,LLnju79@hotmail.com, msn 可以加我。
#### 我认为取 K = 6 * N 比较恰当。

*** 先说了,参加本委员会没有任何好处,只有给分和作苦力 ***
*委员会成员的义务:
* 给分,这个根据个人能力,分多的多给,分少的少给。
* 写代码,加大给分的难度,减少我们给分次数。
* 检察收到的代码,测试程序性能

各个委员会成员 将在第一时间获得最新的进展,并参加评奖活动,其他的还可以商量(这个条件是不是没有吸引力^_^)。

$$$$$$$$$ 评奖办法:$$$$$$$$$$$$
#1. 程序 运行时间( t ) 和 收到程序的时间( d, 从发布之日算起,就是今天为 1 ) 为评价标准。
#2. t * t * d 为判断依据,数值低于最好记录( 初始记录为 本委员会 最佳结果 ) 的获奖。
#3. 评选 特等奖,程序特别优秀的将获得 特奖(intfree呢,强烈建议加入本委员会)。

在 C300A , 128M 下,下列问题已经解决 :
* N=4 K=24 ( 用时 2988ms )
* N=5 K=30 ( 用时 53239ms )
* N=6 K=36 ( 用时 549857ms )
* N=7 K=42 正在进行中,我想我下午下班回家应该可以看到运行结果了,啊,我可怜的破机器(不是我的,是别人的,我帮他折磨电脑)

欢迎大家的踊跃参与,好运获大奖了.......
...全文
1230 102 打赏 收藏 转发到动态 举报
写回复
用AI写文章
102 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kaye 2002-03-01
  • 打赏
  • 举报
回复
to LLnju:
我的回复你的邮件总是不成功,呵呵!今天搜索了好久才看到这个贴子!来完了刚好可以偷学各位大虾的功夫了!真是不好意思了,占便宜了
mathe 2002-02-22
  • 打赏
  • 举报
回复
其实对于N=9,8时也可以用类似的方法进行过滤就行了。
mathe 2002-02-22
  • 打赏
  • 举报
回复
我的代码已经可以对付K是各种值的情况,只是如果K很大时,投机成功的可能性就很小了,效果就很差了。
Bug_Debug 2002-02-22
  • 打赏
  • 举报
回复
试了一下,确实如此。我想对任意 K , 是不是应该首先转化成 连乘 +(-) d 的形式呢。mathe 你看看能不能把你现在的程序稍微改改就能够对付这种情况,解出来我再加分。
mathe 2002-02-22
  • 打赏
  • 举报
回复
#define C1(a) C(a,list1,nSize1)
#define C2(a) C(a,list2,nSize2)
#define C3(a) C(a,list3,nSize3)
#define C4(a) C(a,list4,nSize4)
#define C5(a) C(a,list5,nSize5)

void Show(const int s[4],short type,const char *dis[4]){
int op1,op2,op3,gtype,order;
int a,b,c,d;
const char *porder;
const char *dis4[4];
char array[4][10];
op1=FIRST_OP(type);
op2=SECOND_OP(type);
op3=THIRD_OP(type);
gtype=GRAPH_TYPE(type);
order=NUM_ORDER(type);
porder=orig[order];
a=s[porder[0]-'a'];
b=s[porder[1]-'a'];
c=s[porder[2]-'a'];
d=s[porder[3]-'a'];
if(dis==NULL){
int u;
for(u=0;u<4;++u){
sprintf(array[u],"%d",s[porder[0]-'a']);
dis4[u]=array[u];
}
}else{
int u;
for(u=0;u<4;++u){
dis4[u]=dis[porder[u]-'a'];
}
}
switch(gtype){
case 0:
// op2
// /\
// / \
// op1 op3
// /\ /\
// a bc d
if(op1<2&&op2>=2){
printf("(%s%c%s)%c",dis4[0],opprint[op1],dis4[1],opprint[op2]);
}else{
printf("%s%c%s%c",dis4[0],opprint[op1],dis4[1],opprint[op2]);
}
if(op2>=op3){
printf("(%s%c%s)",dis4[2],opprint[op3],dis4[3]);
}else{
printf("%s%c%s",dis4[2],opprint[op3],dis4[3]);
}
break;
case 1:
// op3
// /\
// op2 d
// /\
// op1 c
// /\
// a b
if(op2<2&&op3>=2){printf("(");}
if(op1<2&&op2>=2){printf("(");}
printf("%s%c%s",dis4[0],opprint[op1],dis4[1]);
if(op1<2&&op2>=2){printf(")");}
printf("%c%s",opprint[op2],dis4[2]);
if(op2<2&&op3>=2){printf(")");}
printf("%c%s",opprint[op3],dis4[3]);
break;
case 2:
// op3
// /\
// op1 d
// /\
// a op2
// /\
// b c
if(op1<2&&op3>=2){printf("(");}
printf("%s%c",dis4[0],opprint[op1]);
if(op1>=op2){printf("(");}
printf("%s%c%s",dis4[1],opprint[op2],dis4[2]);
if(op1>=op2){printf(")");}
if(op1<2&&op3>=2){printf(")");}
printf("%c%s",opprint[op3],dis4[3]);
break;
case 3:
// op1
// /\
// a op3
// /\
// op2 d
// /\
// b c
printf("%s%c",dis4[0],opprint[op1]);
if(op1>=op3){printf("(");}
if(op2<2&&op3>=2){printf("(");}
printf("%s%c%s",dis4[1],opprint[op2],dis4[2]);
if(op2<2&&op3>=2){printf(")");}
printf("%c%s",opprint[op3],dis4[3]);
if(op1>=op3){printf(")");}
break;
case 4:
// op1
// /\
// a op2
// /\
// b op3
// /\
// c d
printf("%s%c",dis4[0],opprint[op1]);
if(op1>=op2){printf("(");}
printf("%dis4[0]%c",dis4[1],opprint[op2]);
if(op2>=op3){printf("(");}
printf("%s%c%s",dis4[2],opprint[op3],dis4[3]);
if(op2>=op3){printf(")");}
if(op1>=op2){printf(")");}
break;
}
}

int C(const int s[4],List list[],int count){
int total=0;//found operations count
int i;
int flag=0;
factor a,b,c,d,r1,r2,r;
int result;
for(i=0;i<count;i++){
int op1,op2,op3,gtype,order;
const char *porder;
short t=list[i].d;
int sel=0;
op1=FIRST_OP(t);
op2=SECOND_OP(t);
op3=THIRD_OP(t);
gtype=GRAPH_TYPE(t);
order=NUM_ORDER(t);
a.down=b.down=c.down=d.down=1;
porder=orig[order];
a.up=s[porder[0]-'a'];
b.up=s[porder[1]-'a'];
c.up=s[porder[2]-'a'];
d.up=s[porder[3]-'a'];
switch(gtype){
case 0:
// op2
// /\
// / \
// op1 op3
// /\ /\
// a bc d
operators[op1](&r1,&a,&b);
operators[op3](&r2,&c,&d);
operators[op2](&r,&r1,&r2);
break;
case 1:
// op3
// /\
// op2 d
// /\
// op1 c
// /\
// a b
operators[op1](&r1,&a,&b);
operators[op2](&r2,&r1,&c);
operators[op3](&r,&r2,&d);
break;
case 2:
// op3
// /\
// op1 d
// /\
// a op2
// /\
// b c
operators[op2](&r1,&b,&c);
operators[op1](&r2,&a,&r1);
operators[op3](&r,&r2,&d);
break;
case 3:
// op1
// /\
// a op3
// /\
// op2 d
// /\
// b c
operators[op2](&r1,&b,&c);
operators[op3](&r2,&r1,&d);
operators[op1](&r,&a,&r2);
break;
case 4:
// op1
// /\
// a op2
// /\
// b op3
// /\
// c d
operators[op3](&r1,&c,&d);
operators[op2](&r2,&b,&r1);
operators[op1](&r,&a,&r2);
break;
}
if(equal_num(&r,60)){
cur_op=t;
flag=1;
return flag;
}else if(equal_num(&r,30)){
cur_op=t;
flag=2;
}else if((flag>=3||flag==0)&&equal_num(&r,20)){
cur_op=t;
flag=3;
}else if((flag>=4||flag==0)&&equal_num(&r,15)){
cur_op=t;
flag=4;
}else if((flag>=5||flag==0)&&equal_num(&r,12)){
cur_op=t;
flag=5;
}else if(!flag&&equal_num(&r,10)){
cur_op=t;
flag=6;
}
}
return flag;
}
mathe 2002-02-22
  • 打赏
  • 举报
回复
除了
试了一下,剩下的好像可以全部手工解出来,对了 mathe ,你的程序里还有几段没有贴出来吧,请发一个完整的程序到我的信箱 LLnju79@hotmail.com。

请到 http://www.csdn.net/expert/topic/536/536891.xml 下领奖,我的分不多了,暂定这么多。

现在 N=10 K=60 已经解决了

1,1,1,1,1,1,1,1,1,1; XX
2,1,1,1,1,1,1,1,1,1; XX
全部有解
比如
2,2,1,1,1,1,1,1,1,1; 2*2*(1+1+1)*(1+1+1+1+1)
Bug_Debug 2002-02-22
  • 打赏
  • 举报
回复
回复不能超过30次,5~5~~5~~~ , Bug_Debug 就是我

***************************************************************
现在继续征解,一般的 对 N=10 ,K 任意继续求解。得出解答的有高分啊,大家努力。
***************************************************************

mathe() : 哎, 3 3 8 8 这组解害死我了,让我以为对更大的数也有如此精妙的解答,5~5~~5~~~。其实只要分解为 op * op + d 形式可能对 N=10 可以得到全部的解答, 上面你剩下的我就只用 6*10 的形式就全部得到了。
LLnju 2002-02-22
  • 打赏
  • 举报
回复
试了一下,剩下的好像可以全部手工解出来,对了 mathe ,你的程序里还有几段没有贴出来吧,请发一个完整的程序到我的信箱 LLnju79@hotmail.com。

请到 http://www.csdn.net/expert/topic/536/536891.xml 下领奖,我的分不多了,暂定这么多。

现在 N=10 K=60 已经解决了

1,1,1,1,1,1,1,1,1,1; XX
2,1,1,1,1,1,1,1,1,1; XX
2,2,1,1,1,1,1,1,1,1; XX
2,2,2,1,1,1,1,1,1,1; XX
2,2,2,2,1,1,1,1,1,1; XX
2,2,2,2,2,1,1,1,1,1; XX
2,2,2,2,2,2,1,1,1,1; (2+2+2+2+2)*(2+1+1+1+1)
2,2,2,2,2,2,2,1,1,1; (2+2+2+2+2)*1*(2+2+1+1)
2,2,2,2,2,2,2,2,1,1; (2+2+2+2+2)*1*1*(2+2+2)
2,2,2,2,2,2,2,2,2,1; (2+2+2+2+2)*(2+2+2)*(2-1)
2,2,2,2,2,2,2,2,2,2; (2+2+2+2+2)*2/2*(2+2+2)
3,1,1,1,1,1,1,1,1,1; XX
3,2,1,1,1,1,1,1,1,1; XX
3,3,1,1,1,1,1,1,1,1; XX
4,1,1,1,1,1,1,1,1,1; XX
5,1,1,1,1,1,1,1,1,1; XX
6,1,1,1,1,1,1,1,1,1; XX
7,1,1,1,1,1,1,1,1,1; (7+1+1+1)*(1+1+1+1+1+1)
8,1,1,1,1,1,1,1,1,1; (8+1+1)*1*(1+1+1+1+1+1)
8,8,8,8,8,8,8,8,1,1; (8+8/8+8/8)*(8-8/8-1/1)
8,8,8,8,8,8,8,8,8,8; (8+8/8+8/8)*(8-8/8-8/8)
9,1,1,1,1,1,1,1,1,1; (9+1)*(1+1+1+1+1+1)*1*1
9,8,8,8,8,8,8,8,1,1; (9+8/8)*(8-8/8-8/8)*1*1
9,8,8,8,8,8,8,8,8,8; (9+8/8)*(8-8/8-8/8)*8/8
9,9,8,8,8,8,8,8,1,1; (9+9-8)*(8-8/8-8/8)*1*1
9,9,8,8,8,8,8,8,8,8; (9+9-8)*(8-8/8-8/8)*8/8
9,9,9,8,8,8,8,8,1,1; (9+9/9)*(8-8/8-8/8)*1*1
9,9,9,8,8,8,8,8,8,8; (9+9/9)*(8-8/8-8/8)*8/8
9,9,9,9,8,8,8,8,1,1; (9+9/9)*(9-8/8-8/8-1)*1
9,9,9,9,8,8,8,8,8,8; (9+9-8)*9/9*(8-8/8-8/8)
9,9,9,9,9,8,8,8,1,1; (9+9/9)*(9-8)*(9-8/8-1-1)
9,9,9,9,9,8,8,8,8,8; (9+9/9)*(9-8)*(9-(8+8+8)/8)
9,9,9,9,9,9,8,8,1,1; (9+9/9)*9/9*(9-8/8-1-1)
9,9,9,9,9,9,8,8,8,8; (9+9/9)*9/9*(9-(8+8+8)/8)
9,9,9,9,9,9,9,8,1,1; (9+9/9)*9/9*(8-9/9-1/1)
9,9,9,9,9,9,9,8,8,8; (9+9/9)*9/9*(8-9/9-8/8)
9,9,9,9,9,9,9,9,1,1; (9+9/9)*9/9*(9-9/9-1-1)
9,9,9,9,9,9,9,9,8,8; (8+9/9+9/9)*(8-9/9-9/9)
9,9,9,9,9,9,9,9,9,8; (9+9/9)*9/9*(8-9/9-9/9)
9,9,9,9,9,9,9,9,9,9; (9+9/9)*9/9*(9-(9+9+9)/9)
LLnju 2002-02-22
  • 打赏
  • 举报
回复
呵呵,不错啊,快要解决问题了,得出了最后几组就可以颁奖了。好像剩下的几组大部分手工就可以解出来。
mathe 2002-02-22
  • 打赏
  • 举报
回复
int t[9][9][9][9];

void fillt(int i1,int i2,int i3,int i4)
{
int u1,u2,u3,u4,tt;
int a[4];
for(u1=-1;u1<=1;++u1)for(u2=-1;u2<=1;++u2)for(u3=-1;u3<=1;++u3)for(u4=-1;u4<=1;++u4){
int c=(u1!=0)+(u2!=0)+(u3!=0)+(u4!=0);
if(i1+u1>=1&&i1+u1<=9&&i2+u2>=1&&i2+u2<=9&&
i3+u3>=1&&i3+u3<=9&&i4+u4>=1&&i4+u4<=9){
a[0]=i1+u1-1;
a[1]=i2+u2-1;
a[2]=i3+u3-1;
a[3]=i4+u4-1;
if(a[0]<a[1]||a[1]<a[2]||a[2]<a[3])
continue;
if(t[a[0]][a[1]][a[2]][a[3]]==0&&t==4)
t[a[0]][a[1]][a[2]][a[3]]=-(1+(u1+1)+((u2+1)<<2)+((u3+1)<<4)+((u4+1)<<6)+(cur_op<<8));
else
t[a[0]][a[1]][a[2]][a[3]]=1+(u1+1)+((u2+1)<<2)+((u3+1)<<4)+((u4+1)<<6)+(cur_op<<8);
}
}
}

int InvalidList[][4]={
{1,1,1,1},
{2,1,1,1},
{2,2,1,1},
{2,2,2,1},
{2,2,2,2},
{3,1,1,1},
{3,2,1,1},
{3,2,2,1},
{3,3,1,1},
{4,1,1,1},
{4,2,1,1},
{5,1,1,1},
{6,1,1,1},
{7,1,1,1},
{7,2,1,1},
{7,7,7,7},
{8,1,1,1},
{8,8,8,8},
{9,1,1,1},
{9,8,8,8},
{9,9,8,8},
{9,9,9,1},
{9,9,9,8},
{9,9,9,9}
};

void output(int a[10]){
int onea[4],ia[4];
char dis[4][20];
char *dp[4];
int u;
for(onea[0]=0;onea[0]<=8;onea[0]++)for(onea[1]=onea[0]+2;onea[1]<=8;onea[1]++)for(onea[2]=onea[1]+2;onea[2]<=8;onea[2]++){
int one=0,i=0;
if(a[8]==1)onea[2]=8;
if(a[onea[0]]>a[onea[0]+1]+1||
a[onea[1]]>a[onea[1]+1]+1||
a[onea[2]]>a[onea[2]+1]+1)
continue;
for(u=0;u<=9;++u){
if(u!=onea[0]&&u!=onea[1]&&u!=onea[2]){
ASSERT(i<4);
ia[i++]=u;
}else{
u++;
}
}
onea[3]=8;
ASSERT(i==4);
i=t[a[ia[0]]-1][a[ia[1]]-1][a[ia[2]]-1][a[ia[3]]-1];
if(i>0||i<0&&a[8]==1){
int u1,u2,u3,u4,op;
int zused=0;
int four1;
if(i<0)i=-i;
u1=((i-1)&3)-1;
u2=(((i-1)>>2)&3)-1;
u3=(((i-1)>>4)&3)-1;
u4=(((i-1)>>6)&3)-1;
four1=((u1!=0)+(u2!=0)+(u3!=0)+(u4!=0)==4);
op=(i-1)>>8;
switch(u1){
case -1:
if(a[onea[0-zused]]==a[onea[0-zused]+1])
sprintf(dis[0],"(%d+%d/%d)",a[ia[0]],a[onea[0-zused]],a[onea[0-zused]+1]);
else
sprintf(dis[0],"(%d+%d-%d)",a[ia[0]],a[onea[0-zused]],a[onea[0-zused]+1]);
break;
case 0:
sprintf(dis[0],"%d",a[ia[0]]);
zused=1;
break;
case 1:
if(a[onea[0-zused]]==a[onea[0-zused]+1])
sprintf(dis[0],"(%d-%d/%d)",a[ia[0]],a[onea[0-zused]],a[onea[0-zused]+1]);
else
sprintf(dis[0],"(%d-%d+%d)",a[ia[0]],a[onea[0-zused]],a[onea[0-zused]+1]);
break;
}
switch(u2){
case -1:
if(a[onea[1-zused]]==a[onea[1-zused]+1])
sprintf(dis[1],"(%d+%d/%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
else
sprintf(dis[1],"(%d+%d-%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
break;
case 0:
if(!zused){
sprintf(dis[1],"%d",a[ia[1]]);
zused=1;
}else{
if(a[onea[1-zused]]==a[onea[1-zused]+1])
sprintf(dis[1],"(%d+%d-%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
else
sprintf(dis[1],"%d*(%d-%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
}
break;
case 1:
if(a[onea[1-zused]]==a[onea[1-zused]+1])
sprintf(dis[1],"(%d-%d/%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
else
sprintf(dis[1],"(%d-%d+%d)",a[ia[1]],a[onea[1-zused]],a[onea[1-zused]+1]);
break;
}
switch(u3){
case -1:
if(four1)
sprintf(dis[2],"(%d+1)",a[ia[2]]);
else if(a[onea[2-zused]]==a[onea[2-zused]+1])
sprintf(dis[2],"(%d+%d/%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
else
sprintf(dis[2],"(%d+%d-%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
break;
case 0:
if(!zused){
sprintf(dis[2],"%d",a[ia[2]]);
zused=1;
}else{
if(a[onea[2-zused]]==a[onea[2-zused]+1])
sprintf(dis[2],"(%d+%d-%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
else
sprintf(dis[2],"%d*(%d-%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
}
break;
case 1:
if(four1)
sprintf(dis[2],"(%d-1)",a[ia[2]]);
else if(a[onea[2-zused]]==a[onea[2-zused]+1])
sprintf(dis[2],"(%d-%d/%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
else
sprintf(dis[2],"(%d-%d+%d)",a[ia[2]],a[onea[2-zused]],a[onea[2-zused]+1]);
break;
}
switch(u4){
case -1:
if(four1)
sprintf(dis[3],"(%d+1)",a[ia[3]]);
else if(a[onea[3-zused]]==a[onea[3-zused]+1])
sprintf(dis[3],"(%d+%d/%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
else
sprintf(dis[3],"(%d+%d-%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
break;
case 0:
if(!zused){
sprintf(dis[3],"%d",a[ia[3]]);
zused=1;
}else{
if(a[onea[3-zused]]==a[onea[3-zused]+1])
sprintf(dis[3],"(%d+%d-%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
else
sprintf(dis[3],"%d*(%d-%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
}
break;
case 1:
if(four1)
sprintf(dis[3],"(%d-1)",a[ia[3]]);
else if(a[onea[3-zused]]==a[onea[3-zused]+1])
sprintf(dis[3],"(%d-%d/%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
else
sprintf(dis[3],"(%d-%d+%d)",a[ia[3]],a[onea[3-zused]],a[onea[3-zused]+1]);
break;
}
dp[0]=dis[0],dp[1]=dis[1],dp[2]=dis[2],dp[3]=dis[3];
Show(ia,op,dp);
printf("\n");
return;
}
}
fprintf(stderr,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d; Not Found\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
num++;
}


void main(int argc,char *argv[])
{
int a[10];
int i1,i2,i3,i4,i5,i6,i7,i8,i9,i10;
int tick=GetTickCount();
initlists();
for(num=0,i1=1;i1<=9;++i1)for(i2=1;i2<=i1;++i2)for(i3=1;i3<=i2;++i3)for(i4=1;i4<=i3;++i4){
int flag;
a[0]=i1,a[1]=i2,a[2]=i3,a[3]=i4;
flag=C1(a);
if(flag==1)
{
fillt(i1,i2,i3,i4);
}
}
num=0;
for(i1=1;i1<=9;++i1)for(i2=1;i2<=i1;++i2)for(i3=1;i3<=i2;++i3){
for(i4=1;i4<=i3;++i4)for(i5=1;i5<=i4;++i5)for(i6=1;i6<=i5;++i6){
for(i7=1;i7<=i6;++i7)for(i8=1;i8<=i7;++i8)for(i9=1;i9<=i8;++i9)for(i10=1;i10<=i9;++i10){
a[0]=i1,a[1]=i2,a[2]=i3,a[3]=i4,a[4]=i5,a[5]=i6,a[6]=i7,a[7]=i8,a[8]=i9,a[9]=i10;
output(a);
}
}
}
fprintf(stderr,"Total %d Not Found\n",num);
fprintf(stderr,"Total Time %d",GetTickCount()-tick);
}
mathe 2002-02-21
  • 打赏
  • 举报
回复
投机结果是对于N==10,K==60我们只需要通过1.5秒的预处理(在PII 233M机器),就可以去掉大部分情况,剩于只有40种情况我们需要全部枚举。

mathe 2002-02-21
  • 打赏
  • 举报
回复
我试着写了个对于N=10,K=60时投机的程序,在PII 233的机器上在运行1.5秒。
结果只有40中情况投机不成功
1,1,1,1,1,1,1,1,1,1; Not Found
2,1,1,1,1,1,1,1,1,1; Not Found
2,2,1,1,1,1,1,1,1,1; Not Found
2,2,2,1,1,1,1,1,1,1; Not Found
2,2,2,2,1,1,1,1,1,1; Not Found
2,2,2,2,2,1,1,1,1,1; Not Found
2,2,2,2,2,2,1,1,1,1; Not Found
2,2,2,2,2,2,2,1,1,1; Not Found
2,2,2,2,2,2,2,2,1,1; Not Found
2,2,2,2,2,2,2,2,2,1; Not Found
2,2,2,2,2,2,2,2,2,2; Not Found
3,1,1,1,1,1,1,1,1,1; Not Found
3,2,1,1,1,1,1,1,1,1; Not Found
3,3,1,1,1,1,1,1,1,1; Not Found
4,1,1,1,1,1,1,1,1,1; Not Found
5,1,1,1,1,1,1,1,1,1; Not Found
6,1,1,1,1,1,1,1,1,1; Not Found
7,1,1,1,1,1,1,1,1,1; Not Found
8,1,1,1,1,1,1,1,1,1; Not Found
8,8,8,8,8,8,8,8,1,1; Not Found
8,8,8,8,8,8,8,8,8,8; Not Found
9,1,1,1,1,1,1,1,1,1; Not Found
9,8,8,8,8,8,8,8,1,1; Not Found
9,8,8,8,8,8,8,8,8,8; Not Found
9,9,8,8,8,8,8,8,1,1; Not Found
9,9,8,8,8,8,8,8,8,8; Not Found
9,9,9,8,8,8,8,8,1,1; Not Found
9,9,9,8,8,8,8,8,8,8; Not Found
9,9,9,9,8,8,8,8,1,1; Not Found
9,9,9,9,8,8,8,8,8,8; Not Found
9,9,9,9,9,8,8,8,1,1; Not Found
9,9,9,9,9,8,8,8,8,8; Not Found
9,9,9,9,9,9,8,8,1,1; Not Found
9,9,9,9,9,9,8,8,8,8; Not Found
9,9,9,9,9,9,9,8,1,1; Not Found
9,9,9,9,9,9,9,8,8,8; Not Found
9,9,9,9,9,9,9,9,1,1; Not Found
9,9,9,9,9,9,9,9,8,8; Not Found
9,9,9,9,9,9,9,9,9,8; Not Found
9,9,9,9,9,9,9,9,9,9; Not Found
Total 40 Not Found
Total Time 1532
LLnju 2002-02-20
  • 打赏
  • 举报
回复
我有一个想法,我想应该可行,但最近来不及写程序了,主要依赖于以下几个事实(在 N == 10 , K = 60下):
* 对 N == 10 , ∑D >= 16 /*( 6 * 10 )*/, 无法组合出 60 的情况应该小于 0.1%。
* 在 可以组合出 60 的情况下,99.9% 可以不需要分数运算,我想也许应该不会再有 像 3,3,8,8 这种情况发生,但我无法证明它。

因此,我把程序的求解过程分解为两个阶段:
1. 全部使用整点运算,计算出大部分的组合情况下的解。
2. 对第一步无解的情况,使用原始的方法求解,我想这种情况将小于50组(除∑D < 16的情况)。

记 S( a1 , a2 , ... , an ) 为 a1 .... an 组合出的全部结果的集合, 我计算了一下,发现对 N = 1 - 9 的情况下,我们完全可以用这种方式保存下来:
*** 对去除 ∏(ai) 的数据, 对 0 - MAXC 可以用 MAXC BITS 来表示,这样在一个集合中查找一个数据的过程非常快。
*** 对 N > 5 , max 可以进一步缩小到 MAXC( 10 - N ) * 60

需要的内存为(对 N < 6 的就不说了 )
* N == 6 : 共有 3003 组数据, 记录每组数据最大需要 9*9*9*9*(9+9)/8 BYTES , 对 ai=5 只需 5*5*5*5*10 / 8 BYTES , 需要的内存将小于 10M。
* N == 7 : 共有 6435 组数据, 记录每组数据需要 60 * 9 * ( 9 + 9 ) / 8 BYTES , 需要内存小于 50M。
* N == 8 : 共有 12870 组数据, 记录每组数据需要 60 * ( 9 + 9 ) / 8 BYTES , 需要内存小于 15M。
* N == 9 : 共有 24310 组数据, 记录每组数据需要 60 * 9 / 8 BYTES , 需要内存小于 2M。

有了 2 - (N-1) 个数据组合的情况求解 N 个数据的组合就很快了,但我想对于 N == 8 , 9 还是分布计算的好点,找个 4 台机子应该不难。

我会找个时间把上面的想法写出来的,谁先搞出来也有大奖啊。
rightyeah 2002-02-20
  • 打赏
  • 举报
回复
有什么结果啦?
rightyeah 2002-02-20
  • 打赏
  • 举报
回复
up
intfree 2002-02-20
  • 打赏
  • 举报
回复
现在的进展如何?
LLnju 2002-02-19
  • 打赏
  • 举报
回复
大家新年好啊,这个问题继续征解,明天开始计时吧,三天后颁奖,不要又落空啊
leojay 2002-02-11
  • 打赏
  • 举报
回复
up gz 一下
chaomao 2002-02-10
  • 打赏
  • 举报
回复
如果N的大小没定,解为无穷。
starfish 2002-02-10
  • 打赏
  • 举报
回复
here are some theorems about the game of 24, and thus we can design a algorithm
to solve the problem in O(nlogn), where n is the size of the multiset S.

Definition 1
Give a multiset S of rational numbers, let f(S) be a multiset of rational
numbers defined as follows: if S is an empty or a singleton multiset, then f(S) is S;
if S cotains at least two elements, then f(S) is the union of f( (S/{r1, r2})∪ r ),
for r = r1+r2, r1-r2, r1*r2 and r1/r2 (if r2≠0), where r1, r2 range over all possible
pairs of rational numbers in S.

Definition 2
Given four integers n1, n2, n3 and n4 between 1 and 13, the game-of-24 is a
game that determines whether 24 is in the set of f( {n1, n2, n3, n4} ).

Definition 3
Given two multsets S1 and S2, we define comb(S1, S2) as the multiset that
contains all rational number r of form r1+r2, r1-r2, r1*r2 or r1/r2,
where r1 and r2 range over S1 and S2, respectively.

Theorem 4
Given a multiset of rational numbers S with at least two elements, we have
that f(S) is the union of comb(f(S1), f(S\S1)), where S1 ranges over all
possible subsets of S excluding Φ and S.
加载更多回复(82)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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