用你的智慧,创造奇迹

wljcr 2001-05-24 11:01:00
有31个数进行排列,分为以下几种情况
1、全部相邻 例如:2、3、4、5、6、7、8 etc。
2、六个相邻 例如:2、3、4、5、6、7、13,2、4、5、6、7、8、9 etc。
3、五个相邻 例如:2、3、4、5、6、8、9, 2、4、5、6、7、8、12,etc。
4、四个相邻 例如:2、3、4、5、7、8、9, 2、3、5、6、7、8、10,etc。
5、三个相邻 例如:2、3、4、6、7、8、10,2、4、5、6、8、9、12,etc。
7、两个相邻 例如:2、3、4、6、7、8、23…………
8、互不相邻 例如:2、4、6、9、11、14………………
以上每一种情况不能相互包含,比如四个相邻的情况不能包含五个相邻的情况,当然也不能包含六个相邻的情况,请各位大虾指教一二
...全文
1482 85 打赏 收藏 转发到动态 举报
写回复
用AI写文章
85 条回复
切换为时间正序
请发表友善的回复…
发表回复
wljcr 2001-06-08
  • 打赏
  • 举报
回复
coolcch 2001-06-08
  • 打赏
  • 举报
回复
to kingsong(牛大锅):
认栽!
你的算法好!
我已经懒的再改进了!
wljcr 2001-06-07
  • 打赏
  • 举报
回复
好!等等先!
kingsong 2001-06-07
  • 打赏
  • 举报
回复
coolcch():我又改进了一下,几乎可以使没次循环都能产生解,比我原来那个几乎快了一倍。我算了一个(31,20,5),只计算组数,不输出结果,在PIII450上用时7秒,结果是21877581。呵呵,怎么样,比比谁快。不过程序可读性就不好了。
wljcr(寻风):可以结帐了。

#include "alloc.h"
#include "stdio.h"

int maxnum,m,n;
int *s;
double aaa;

void myoutput()
{ int j;
/* for (j=1;j<=m;j++)
printf("%d ",s[j]);
printf("\n");
getch();*/
aaa=aaa+1;
}

int myjudge(int h)
{int i;
for (i=1;i<=h-n;i++)
{if (s[i+n-1]-s[i]==n-1)
{ if (i<m-n-1)
return(1);
else
return(2);
}
}
return(0);
}

int howlong(int h)
{int i,leng;
leng=1;
for (i=h-1;i>0;i--)
{if (s[h]-s[i]==h-i)
leng++;
else
break;
}
return(leng);
}

generate(int from,int num)
{int i;
if (num>m)
{myoutput();
return;
}
for (i=from;i<=maxnum-(m-num);i++)
{s[num]=i;
if (num<m)
generate(i+1,num+1);
else
myoutput();
}
}

void myget(int from,int num)
{int i,j,k,ret_val,ret_long,oldfrom,oldnum;
if ((m-num+2)==n)
{oldfrom=from;
oldnum=num;
ret_long=howlong(num-1);
for (j=ret_long;j<n;j++)
{s[oldnum]=oldfrom;
oldnum++;
oldfrom++;
}
generate(oldfrom+1,oldnum);
ret_val=myjudge(num-1);
if (ret_val!=0)
{for (j=ret_long+1;j<=n;j++)
{oldnum=num;
oldfrom=from;
for (k=1;k<=n-j;k++)
s[oldnum++]=oldfrom++;
generate(oldfrom+1,oldnum);
}
}
}
else
{for (i=from;i<=maxnum-(m-num);i++)
{ s[num]=i;
if ((num>n) && (s[num]-s[num-n]==n))
continue;
myget(i+1,num+1);
}
}
}

main()
{maxnum=31;
m=20;
n=5;
aaa=0;
s=malloc(sizeof(int)*(m+1));
myget(1,1);
printf("%f\n",aaa);
}
wljcr 2001-06-07
  • 打赏
  • 举报
回复
wljcr 2001-06-06
  • 打赏
  • 举报
回复
wljcr 2001-06-06
  • 打赏
  • 举报
回复
关注!
wljcr 2001-06-06
  • 打赏
  • 举报
回复
我还没有使用你们的程序,我最近有点忙,到时候我在加分,还有没有别人知道?
coolcch 2001-06-04
  • 打赏
  • 举报
回复
to kingsong(牛大锅):
too slowly.
after i ran it after 1 min and 20 sec, i cut it.(PIII)
my prg can be 通用(sorry! i cannnot input chinese), changing a little.
and it is so fast.
my prg's cycle no 多余, but yours......
my 算法:
1 |3 |5|7 |9
+ + +|+ +|+|+ |+
0 1 2|2 3|3|3 |3
= = =|= =|=|= |=
1 2 3|5 6|8|10|12

coolcch 2001-06-04
  • 打赏
  • 举报
回复
Calculate 31,7,3
tell me the count.

kingsong 2001-06-04
  • 打赏
  • 举报
回复
sry,严重失误
for (i=from;i<=maxnum-(7-num);i++)
确实应该是
for (i=from;i<=maxnum-(m-num);i++)
谢coolcch(),等我有时间在琢磨你的程序,我只是看了你的Get1xCall用了7重循环
wljcr 2001-06-04
  • 打赏
  • 举报
回复
kingsong(牛大锅):
不好意思,我在装下超过32767纪录时,通常是每一行放两个或者三个纪录,这样就不用再加一个listbox了
coolcch 2001-06-04
  • 打赏
  • 举报
回复
for (i=from;i<=maxnum-(7-num);i++)中, 7是否要改为m呢?(猜的)

不知道 m, n 大一点的时候, 谁的程序更有优势呢? 呵呵!
哎! 我的好胜心太强了!
coolcch 2001-06-04
  • 打赏
  • 举报
回复
(31,7,3)共431250条组合。OK!!!
速度差不多
我的那个程序,只要:
1. 用Get1xCallx, 不用Get1xCall
2. 把#define XXX ### 改为 int XXX=###;
3. 几个数组都动态分配内存
4. 把程序中的循环最大值的6改为 GETNUM
就可通用了
为什么你会觉得不能通用呢?

哎!
花了大力气, 想尽可能优化. 结果速度差不多.
算了吧! 你的程序还好懂些呢!

kingsong 2001-06-04
  • 打赏
  • 举报
回复
wljcr(寻风):我想请教一下,用listbox1怎么装下超过32767条记录
用Append或Items.Add都不行,用memo也不行。
以前我也碰到过,那时我用的是两个listbox来装40000条记录。
kingsong 2001-06-04
  • 打赏
  • 举报
回复
我改好了,肯定能用,(31,7,3)共431250条组合。
在我的PIII450上,用重定向输出到文件,用时4秒。
coolcch(),我已经有点明白你的思路了,不过你这样不可能做到通用而不是只用changing a little。不好意思,我没有看懂你的程序。

#include "alloc.h"
#include "stdio.h"

int maxnum,m,n;
int *s;

void myoutput()
{ int j;
for (j=0;j<m;j++)
printf("%d ",s[j]);
printf("\n");
}

int myjudge()
/* 判断这组数是否可能
返回值 0-不可能
1-可能,但不是最后n个数才是连续
2-可能,是最后n个数才是连续
*/
{int i;
for (i=0;i<=m-n;i++) /*这里出问题,原来的是i<=m-n-1*/
if (s[i+n-1]-s[i]==n-1)
{if (i<m-n-1)
return(1);
else
return(2);
}
return(0);
}

void myget(int from,int num)
{int i,ret_val;
if (num==m)
/* 递归结束 */
{s[num-1]=from;
if (s[num-1]-s[num-n-1]==n)
{ret_val=1;
from++;
}
else
ret_val=myjudge();
if (ret_val==0) return;
if (ret_val==2)
{myoutput();
return;
}
for (i=from;i<=maxnum;i++)
{s[num-1]=i;
myoutput();
}
}
else
/* 递归 */
{ for (i=from;i<=maxnum-(7-num);i++)
{ s[num-1]=i;
if ((num>n) && (s[num-1]-s[num-n-1]==n))
/* 有大于n个连续的数 ,跳过 */
continue;
myget(i+1,num+1);
}
}
}

main()
{maxnum=31;
m=7;
n=3;
aaa=0;
s=malloc(sizeof(int)*m);
myget(1,1);
}
kingsong 2001-06-04
  • 打赏
  • 举报
回复
coolcch():(31,7,3),你的结果有几条,我怎么只有337870条
但我算(10,7,3)共有29条,结果是对的。
不知道我程序哪里错了。
kingsong 2001-06-04
  • 打赏
  • 举报
回复
coolcch():不知道你说的3秒钟得到结果,是什么结果,光是一个共有几组数吗,如果是将所有组合显示在屏幕上,不可能有这么快。
我的程序好像还有点问题,我再改改。
能把你的算法再讲讲清楚吗
wljcr 2001-06-02
  • 打赏
  • 举报
回复
等一会儿,我先看看
kingsong 2001-06-02
  • 打赏
  • 举报
回复
为什么点管理才能看到我的流言
:(
加载更多回复(65)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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