请教9*9阵列排序的算法 ( 积分: 100 )

  • 主题发起人 主题发起人 tranke
  • 开始时间 开始时间
你可以定义A1[j]....A9[j]来判断同一行中有没出现重复的数
定义B1.....B9来判断同一列中有没出现重复的数
也就是说,当你给C[j]附值的时候,你就只要判断Ai和Bj[j]
比如给C[3][4]附值的时候,只要判断A3和B4[j]中有没出现重复的数就可以了
 
感谢各位,由于家里不能上网!
我现在来看看各位建议的算法。
chaos518,你说的算法是不可行的,因为最终会存在至少9各数无法插入,不信你可以试试。
 
那就只能这样了, 先随即出第一排A[1],A[2],。。。A[9],
然后第二排的时候就是A[2]。。。A[9],A[1]
第三排的时候就是A[3]A[4]。。。A[9]A[1]A[2]
到最后一排的时候就是A[9]。。。。。A[8]
不过这样虽然能得到你要的结果,但肯定不是全部,实在想不出什么好办法了。
不过这个也能蒙混过关的吧,嘿嘿
 
这个跟ak_2005最开始说的不是一样吗!
问题是没有这么顺序,要考虑到有时已经存在的各个位置的数字,再来填充,你再仔细看看前面的解说吧
 
顶chaos518,在chaos518的基础上再把每列的顺序随机,就是所有的结果了,我是这么想的,赫赫[:D]
 
To divelove2003,你试过没有?麻烦你试试后再来发表高见好吗?
跟你说,一定会出现存在几个数无法填入的!因为填入了就变成重复了!!!
 
我搞了一下午,总算找到此例
6 2 7
5
4
1
4
3
1
9
8
的算法解,但是就这一个例子不能保证算法正确性,你再给出你无法解决的几个例子吧
 
谢谢cactus123456,本题的意思是阵列中可能存在某些位置存在一些数,然后我们再来填充其它的数并且要符合题意,我上面给出的是一个可能存在的例子,并不是具体的问题,知道我意思吗?我到现在也还没有找到具体的解决方法,郁闷啊
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,k:integer;
adj,adv:integer;
ss:string;
blline,blfind:boolean;
matrix: array [1..9,1..9] of integer;
mcopy:array [1..9] of integer;
//------------------------------------
//列检测
function checkrownum(row:integer):boolean;
var
i:integer;
count:array [1..9] of integer;
begin
for i:=1 to 9do
count:=0;
for i:=1 to 9do
begin
if (matrix[i,row]>0) and (matrix[i,row]<10) then
inc(count[matrix[i,row]]);
end;
result:=true;
for i:=1 to 9do
begin
if count>1 then
begin
result:=false;
break;
end;
end;
end;
//------------------------------------
//行检测
function checkcownum(cow:integer):boolean;
var
i:integer;
count:array [1..9] of integer;
begin
for i:=1 to 9do
count:=0;
for i:=1 to 9do
begin
if (matrix[cow,i]>0) and (matrix[cow,i]<10) then
inc(count[matrix[cow,i]]);
end;
result:=true;
for i:=1 to 9do
begin
if count>1 then
begin
result:=false;
break;
end;
end;
end;
//------------------------------------
begin
adv:=0;
adj:=0;
while truedo
begin
//初始化
for i:=1 to 9do
for j:=1 to 9do
begin
matrix[i,j]:=0;
end;
//初始值
// 1 2 3 4 5 6 7 8 9
//1 6 2 7
//2 5
//3 4
//4 1
//5 4
//6 3
//7 1
//8 9
//9 8
//赋初值
matrix[1,1]:=6;
matrix[1,5]:=2;
matrix[1,9]:=7;
matrix[2,3]:=5;
matrix[3,2]:=4;
matrix[4,7]:=1;
matrix[5,1]:=4;
matrix[6,5]:=3;
matrix[7,1]:=1;
matrix[8,9]:=9;
matrix[9,1]:=8;
//检测初值的正确性
for i:=1 to 9do
begin
if not checkrownum(i) then
showmessage('初始化error');
if not checkcownum(i) then
showmessage('初始化error');
end;
//显示初值
memo1.Lines.Clear;
for i:=1 to 9do
begin
ss:='';
for j:=1 to 9do
begin
ss:=ss+' '+inttostr(matrix[i,j]);
end;
memo1.Lines.Add(ss);
end;
//运算
//checkrownum(j) and checkcownum(i)
//快速填充
for i:=1 to 9do
begin
//复制行副本
for j:=1 to 9do
mcopy[j]:=matrix[i,j];
adj:=adv;
while truedo
begin
//保证此行正确
blline:=true;
for j:=1 to 9do
if matrix[i,j]=0 then
begin
blfind:=false;
for k:=0 to 8do
begin
matrix[i,j]:=((k+adj) mod 9)+1;
if checkrownum(j) and checkcownum(i) then
begin
blfind:=true;
break;
end;
end;
if not blfind then
begin
blline:=false;
break;
end;
end;
if blline then
break
else
begin
inc(adj);
for j:=1 to 9do
matrix[i,j]:=mcopy[j];
if adj>18 then
break;
end;
end;
//end while
end;
//验证结果
adj:=0;
for i:=1 to 9do
for j:=1 to 9do
begin
if matrix[i,j]=0 then
begin
inc(adj);
break;
end;
end;
//结果判断
if adj>0 then
begin
inc(adv);
if adv>9 then
break;
end
else
break;
end;
//显示结果
memo2.Lines.Clear;
//显示adv
memo2.Lines.Add('========adv='+inttostr(adv)+'===========');
if adj=0 then
begin
for i:=1 to 9do
begin
ss:='';
for j:=1 to 9do
begin
ss:=ss+' '+inttostr(matrix[i,j]);
end;
memo2.Lines.Add(ss);
end;
end
else
begin
memo2.Lines.Add('无解');
end;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
i,j,k:integer;
adj,adv:integer;
ss:string;
blline,blfind:boolean;
matrix: array [1..9,1..9] of integer;
mcopy:array [1..9] of integer;
//------------------------------------
//列检测
function checkrownum(row:integer):boolean;
var
i:integer;
count:array [1..9] of integer;
begin
for i:=1 to 9do
count:=0;
for i:=1 to 9do
begin
if (matrix[i,row]>0) and (matrix[i,row]<10) then
inc(count[matrix[i,row]]);
end;
result:=true;
for i:=1 to 9do
begin
if count>1 then
begin
result:=false;
break;
end;
end;
end;
//------------------------------------
//行检测
function checkcownum(cow:integer):boolean;
var
i:integer;
count:array [1..9] of integer;
begin
for i:=1 to 9do
count:=0;
for i:=1 to 9do
begin
if (matrix[cow,i]>0) and (matrix[cow,i]<10) then
inc(count[matrix[cow,i]]);
end;
result:=true;
for i:=1 to 9do
begin
if count>1 then
begin
result:=false;
break;
end;
end;
end;
//------------------------------------
begin
adv:=0;
adj:=0;
while truedo
begin
//初始化
for i:=1 to 9do
for j:=1 to 9do
begin
matrix[i,j]:=0;
end;
//初始值
// 1 2 3 4 5 6 7 8 9
//1 6 2 7
//2 5
//3 4
//4 1
//5 4
//6 3
//7 1
//8 9
//9 8
//赋初值
matrix[1,1]:=6;
matrix[1,5]:=2;
matrix[1,9]:=7;
matrix[2,3]:=5;
matrix[3,2]:=4;
matrix[4,7]:=1;
matrix[5,1]:=4;
matrix[6,5]:=3;
matrix[7,1]:=1;
matrix[8,9]:=9;
matrix[9,1]:=8;
//检测初值的正确性
for i:=1 to 9do
begin
if not checkrownum(i) then
showmessage('初始化error');
if not checkcownum(i) then
showmessage('初始化error');
end;
//显示初值
memo1.Lines.Clear;
for i:=1 to 9do
begin
ss:='';
for j:=1 to 9do
begin
ss:=ss+' '+inttostr(matrix[i,j]);
end;
memo1.Lines.Add(ss);
end;
//运算
//checkrownum(j) and checkcownum(i)
//快速填充
for i:=1 to 9do
begin
//复制行副本
for j:=1 to 9do
mcopy[j]:=matrix[i,j];
adj:=adv;
while truedo
begin
//保证此行正确
blline:=true;
for j:=1 to 9do
if matrix[i,j]=0 then
begin
blfind:=false;
for k:=8do
wnto 0do
begin
matrix[i,j]:=((k+adj) mod 9)+1;
if checkrownum(j) and checkcownum(i) then
begin
blfind:=true;
break;
end;
end;
if not blfind then
begin
blline:=false;
break;
end;
end;
if blline then
break
else
begin
inc(adj);
for j:=1 to 9do
matrix[i,j]:=mcopy[j];
if adj>18 then
break;
end;
end;
//end while
end;
//验证结果
adj:=0;
for i:=1 to 9do
for j:=1 to 9do
begin
if matrix[i,j]=0 then
begin
inc(adj);
break;
end;
end;
//结果判断
if adj>0 then
begin
inc(adv);
if adv>9 then
break;
end
else
break;
end;
//显示结果
memo2.Lines.Clear;
//显示adv
memo2.Lines.Add('========adv='+inttostr(adv)+'===========');
if adj=0 then
begin
for i:=1 to 9do
begin
ss:='';
for j:=1 to 9do
begin
ss:=ss+' '+inttostr(matrix[i,j]);
end;
memo2.Lines.Add(ss);
end;
end
else
begin
memo2.Lines.Add('无解');
end;

end;

end.
 
好的,我试试!
不过没想到你是用memo,我用的是stringGrid这个倒比较直观
 
当然也存在正解 for k:=0 to 8do
和反解
for k:=8do
wnto 0do
都无解的情况,但是你还可以通过中间求解比如5+-1,等方法求出解,此思路,供参考
 
谢谢,测试中,有问题我会提出来
 
>>可以通过中间求解比如5+-1,等方法求出解,此思路,供参考?
请问cactus123456,“5+-1”是什么意思呢?
的确,存在一些阵列无法自动排列出来,看来是需要再改进算法!
 
求解过程就是排列组合的过程,最简单的构造就是
1,2,3,4,5,6,7,8,9 正序
9,8,7,6,5,4,3,2,1 倒序
我的意思就是你可以在构造一个中间开始的顺序,规则就是+-1
5,6,4,7,3,8,2,9,1 因为这种训序有规律,可以算出来。
if (k mod 2)=0 then
matrix[i,j]:=(4-(k div 2)+adj) mod 9+1
else
matrix[i,j]:=(4+(k div 2)+1+adj) mod 9+1;
5,4,6,3,7,2,8,1,9 等等
阵列的全解应该是个天文数字,因为排列组合的方法太多了9!
 
明白了,我试试吧,明天我再上来
 
问题的算法还需要完善,不过,我打算结帖了,谢谢大家
同时,请cactus123456到这里另外领分,很感谢你的指点
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3223981
 
后退
顶部