数字排列问题(pascal)
列出所有从数字1到数字n的连续自然数的排列,要求所产生的任一数字序列中不允许出现重复的数字(1<=n<=9)附(我的代码(pascal)):programszpl;lab...
列出所有从数字1到数字n的连续自然数的排列,要求所产生的任一数字序列中不允许出现重复的数字(1<=n<=9)
附(我的代码(pascal)):
program szpl;
label 1,2;
var a:array[1..9] of integer;
i,j,k,l,n,m:integer;
f1,f2:text;
begin
assign(f1,'1.in');
assign(f2,'1.out');
reset(f1);
readln(f1,n);
close(f1);
rewrite(f2);
for i:=1 to n do
a[i]:=i;
i:=n;
while m=0 do
begin
for j:=1 to n-1 do
for k:=j+1 to n do
if a[j]=a[k] then goto 1;
for j:=1 to n do
begin
write(f2,a[j],' ');
if a[j]=n+1-j then m:=m+1;
end;
if m=n then goto 2 else m:=0;
writeln(f2);
1: a[i]:=a[i]+1;
if a[i]>n then begin a[i]:=1; l:=i-1; a[l]:=a[l]+1;while a[l]>n do begin a[l]:=1; l:=l-1;a[l]:=a[l]+1; end; end;
end;
2:close(f2);;
end.
答案是对的,但1~8能在1秒内输出,9需要十几秒,优化很久都不行,请帮忙改进一下我的代码(不要用其他算法,仅仅是优化我的代码)
2楼的,从哪粘的?我又没用过程。
1楼的,我之前用了过程,但结果少了很多,输入3的时候,只有3个(是用中学高级本上的过程描述),请给我一个用过程的程序,谢谢
3楼的程序是行的,但大家能否将我的程序判重部分简化?经计算,那里耗时太长。 展开
附(我的代码(pascal)):
program szpl;
label 1,2;
var a:array[1..9] of integer;
i,j,k,l,n,m:integer;
f1,f2:text;
begin
assign(f1,'1.in');
assign(f2,'1.out');
reset(f1);
readln(f1,n);
close(f1);
rewrite(f2);
for i:=1 to n do
a[i]:=i;
i:=n;
while m=0 do
begin
for j:=1 to n-1 do
for k:=j+1 to n do
if a[j]=a[k] then goto 1;
for j:=1 to n do
begin
write(f2,a[j],' ');
if a[j]=n+1-j then m:=m+1;
end;
if m=n then goto 2 else m:=0;
writeln(f2);
1: a[i]:=a[i]+1;
if a[i]>n then begin a[i]:=1; l:=i-1; a[l]:=a[l]+1;while a[l]>n do begin a[l]:=1; l:=l-1;a[l]:=a[l]+1; end; end;
end;
2:close(f2);;
end.
答案是对的,但1~8能在1秒内输出,9需要十几秒,优化很久都不行,请帮忙改进一下我的代码(不要用其他算法,仅仅是优化我的代码)
2楼的,从哪粘的?我又没用过程。
1楼的,我之前用了过程,但结果少了很多,输入3的时候,只有3个(是用中学高级本上的过程描述),请给我一个用过程的程序,谢谢
3楼的程序是行的,但大家能否将我的程序判重部分简化?经计算,那里耗时太长。 展开
展开全部
1. 建议不要用const,
在主程序上readln(n);
2. a[1]:=i;
这里是错的,应该是a[i]:=i;你写成了a[1]
3. for i:=1 to n do
begin
a[1]:=i;
find(2)
end
这里find(2),不要放在循环里面,正确的是
for i:=1 to n do
begin
a[1]:=i;
end
find(1);
4.建一个数组判断I是否重复
b:array[1..100]of boolean;
刚开始所有的I都是false fillchar(b,sizeof(b),false);
5. for i:=1 to n do
for j:=1 to k-1 do
begin
if i<>a[j] then begin
a[k]:=i;
find(k+1)
end
end
然后这里就改成
for i:=1 to n do
begin
if b[i]=false then begin
b[i]:=true
a[k]:=i;
find(k+1);
b[i]:=false;
end
还有不明白的再问。
end
在主程序上readln(n);
2. a[1]:=i;
这里是错的,应该是a[i]:=i;你写成了a[1]
3. for i:=1 to n do
begin
a[1]:=i;
find(2)
end
这里find(2),不要放在循环里面,正确的是
for i:=1 to n do
begin
a[1]:=i;
end
find(1);
4.建一个数组判断I是否重复
b:array[1..100]of boolean;
刚开始所有的I都是false fillchar(b,sizeof(b),false);
5. for i:=1 to n do
for j:=1 to k-1 do
begin
if i<>a[j] then begin
a[k]:=i;
find(k+1)
end
end
然后这里就改成
for i:=1 to n do
begin
if b[i]=false then begin
b[i]:=true
a[k]:=i;
find(k+1);
b[i]:=false;
end
还有不明白的再问。
end
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我想说的是,你的程序用了goto语句后就破坏了程序的协调性,难以对其进行优化,大牛的程序没有goto语句就是因为程序自顶向下的设计方式是最简单的,优化的话最好做个过程,用n个循环嵌套看看也不美观,对吧。
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
要用回溯法,程序如下,需要说明看这个网页
http://zhidao.baidu.com/question/197472333.html
var
a:array[0..100]of integer;
n,i:integer;
procedure make(p:integer);
var i,j,k:integer;
b:array[0..100]of integer;
begin
if p=n then begin for i:=1 to n do write(a[i],' '); writeln;end
else
for i:=p to n do
begin
j:=a[i]; a[i]:=a[p]; a[p]:=j;
b:=a;
make(p+1);
a:=b;
end;
end;
begin
readln(n);
for i:=1 to n do a[i]:=i;
make(1);
end.
http://zhidao.baidu.com/question/197472333.html
var
a:array[0..100]of integer;
n,i:integer;
procedure make(p:integer);
var i,j,k:integer;
b:array[0..100]of integer;
begin
if p=n then begin for i:=1 to n do write(a[i],' '); writeln;end
else
for i:=p to n do
begin
j:=a[i]; a[i]:=a[p]; a[p]:=j;
b:=a;
make(p+1);
a:=b;
end;
end;
begin
readln(n);
for i:=1 to n do a[i]:=i;
make(1);
end.
参考资料: http://zhidao.baidu.com/question/197472333.html
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不可能有重复
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询