50分求购算法(有谁会)(50分)

  • 主题发起人 主题发起人 快刀不快
  • 开始时间 开始时间
我上学的时候研究过,现在没有精力了~~~~~
 
对不起 对不起
丢脸了!
下次不敢了!
 
这个排列的种数有8!*7!*6!*5!*4!*3!*2!*1!之多吗。学习
 
unit Unit1;
interface
uses
Windows,forms,StdCtrls, Classes, Controls,SysUtils;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;

const
x=8;//x=byte;
:)
var
Form1: TForm1;
k:array[1..x,1..x]of byte;
implementation
{$R *.DFM}
function GetRand(a,b:byte):byte;
begin
result:=a+random(b-a+1);
end;

procedure cls_k;
var
a,b:byte;
begin
for a:=1 to x do
for b:=1 to x do
k[a,b]:=0;
end;

procedure Get_k2(n:byte);
var
a,b,c,d:byte;
begin
d:=0;
while true do
begin
c:=GetRand(1,x);b:=0;
for a:=1 to x do
if c=k[n,a] then
begin
b:=1;break;
end;
if b=0 then
begin
d:=d+1;
k[n,d]:=c;
if d=x then
exit;
end;
end;
end;

procedure Get_k1;
var
a,b,c,d:byte;
label xx;
begin
Get_k2(1);
a:=2;
while true do
begin
Get_k2(a);d:=1;
for b:=1 to x do
for c:=1 to x do
if (a<>b)and(k[a,c]=k[b,c]) then
begin
d:=0;
goto xx;
end;
xx:
if d=1 then
begin
if a=x then
break;
a:=a+1;
end else
for c:=1 to x do
k[a,c]:=0;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a,b:byte;
s:string;
begin
memo1.clear;
Application.ProcessMessages;
RandSeed:=GetRand(1,255);
cls_k;
Get_k1;
for a:=1 to x do
begin
s:='';
for b:=1 to x do
s:=s+inttostr(k[a,b])+',';
memo1.Lines.Add(copy(s,1,length(s)-1));
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
end;

end.
 
运行以下代码你就会明白!!!!!!!!

procedure TForm1.Button1Click(Sender: TObject);
var
m,n,i,j,n2,n3,nnn:integer;
nn:array[0..7,0..7] of integer;
s:string;
begin
n:=8;
m:=0;
for i:=0 to n-1 do
begin
inc(m);
for j:=0 to n-1 do
begin
nn[i,j]:=(m+j) mod n;
if nn[i,j]=0 then
nn[i,j]:=n;
end;
end;
//显示交换前
s:='';
for i:=0 to n-1 do
begin
for j:=0 to n-1 do
s:=s+' '+inttostr(nn[i,j]);
s:=s+#13;
end;
showmessage(s);
nnn:=0;
Randomize;
while nnn<100 do
begin
m:=Random(2);
/// 1 交换行,0交换列
n2:=Random(n);
n3:=Random(n);
//交换的两和或两列
if m=1 then
begin
for i:=0 to n-1 do
begin
j:=nn[n2,i];
nn[n2,i]:=nn[n3,i];
nn[n3,i]:=j;
end;
end else
begin
for i:=0 to n-1 do
begin
j:=nn[i,n2];
nn[i,n2]:=nn[i,n3];
nn[i,n3]:=j;
end;
end;
inc(nnn);
end;

//显示交换后
s:='';
for i:=0 to n-1 do
begin
for j:=0 to n-1 do
s:=s+' '+inttostr(nn[i,j]);
s:=s+#13;
end;
showmessage(s);
end;
 
非常感谢form2和jsxjd的代码。可万分遗憾的是他们都没有解决。
form2,我执行了你的程序,先是能给出随机系列(8*8的方阵),但我仔细观察以后,发现
过不了多久,它就会重复出现。按照道理,应该不会重复的。你能不能再思考一下。
jsxjd显然是没有领会我的意思,你的代码只能给出两种排列。而我要求的是随机排列。
请大家再考虑一下,我相信各位能解决的。
重申一下,我要求的是随机排列。
 
“过不了多久,它就会重复出现”什么意思?
是指第N个8*8=第M个8*8?类似于:
1:
6,7,5,2,3,8,1,4
8,4,1,5,6,7,2,3
2,3,4,1,5,6,7,8
1,5,8,4,7,2,3,6
7,8,2,3,1,4,6,5
5,1,6,7,8,3,4,2
4,6,3,8,2,1,5,7
3,2,7,6,4,5,8,1
。。。。。等于
100:
6,7,5,2,3,8,1,4
8,4,1,5,6,7,2,3
2,3,4,1,5,6,7,8
1,5,8,4,7,2,3,6
7,8,2,3,1,4,6,5
5,1,6,7,8,3,4,2
4,6,3,8,2,1,5,7
3,2,7,6,4,5,8,1
如果是的话,我的程序不能保证执行N次后和第一个8*8不相同
办法应该是有的,我认为用我现在的方法思路来限制,太繁琐了,虽然可能可以保证它的唯一
 
form2,是这个意思:如第1到第8个序列完全不一样,可是第9个和第1个序列一样,第10个序列和
第2个序列一样。也就是开始重复以前出现的序列,而且是按顺序的重复。
你能不能再考虑一下。
 
还有,难道你要全部排列出来?并且各矩阵体还不能是顺序的,要唯一的随机?
量太大了,如果要顺序的话,应该没问题
 
对,确实是有,这应该是我程序的随机代码没处理好!
 
把这一句去掉:
//RandSeed:=GetRand(1,255);
或者
function GetRandint(a,b:integer):integer;
begin
result:=a+random(b-a+1);
end;
。。。。
RandSeed:=GetRandint(1,maxint);
或者
把这一句去掉://RandSeed:=GetRand(1,255);
procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
RandSeed:=GetRandint(1,Maxint);//+这一句
tmp:=tstringlist.create;
end;
 
第二个 showmessage(s);
的结果每次是不一样的!!!!!!!!!1
 
to form2,把那句去掉之后,其它都不用改就可以了。
to jsxjd,果然是排名第一的DFW。是我弄错了,你的随机排列没有一样。我昨天没有调试。
form2和jsxjdd的方法不一样。一个是先产生随机数,然后进行判断有否重复,没有,则进入。
如果有再产生新的随机数。一个是先产生固定排列,然后在一个100次的循环里面产生三个随机数
分别判断这次循环是进行列还是行交换,是哪两行或哪两列交换。最后得到一个随机排列。
大家讨论一下,这两种算法,哪个更好,好在哪里?
yisan在哪里。
 
发分了,非常感谢各位大侠,人人有分。欢迎大家继续在我的新帖中讨论,up
form2和jsxjd,分手有点少了,不好意思。所以我结束本帖,在新帖中等待各位,并补偿两位的
分数。新帖是该帖的后续问题。
 

Similar threads

后退
顶部