求 free Pascal 程序设计的一道题,关于全排列

作者&投稿:寿怕 (若有异议请与网页底部的电邮联系)
free pascal 全排列~

这是我写的,希望能帮助你:
var
a:array[1..9]of boolean;
b:array[1..9]of integer;
n,i,j:integer;
procedure try(i:integer);
var
j:integer;
begin
if i=n+1 then begin writeln;for j:=1 to n do write(b[j],' '); end;
for j:=1 to n do
if a[j] then
begin
a[j]:=false;
b[i]:=j;
try(i+1);
a[j]:=true;
end;
end;
begin
fillchar(a,sizeof(a),true);
fillchar(b,sizeof(b),0);
read(n);
try(1);
end.
都对,要加分哦~
O(∩_∩)O~

顺序结构嘛,当然 可以 一步一步来:x1 = x1/3;x2 = (x1+x2)/3;x3 = (x2+x3)/3;x4 = (x3+x4)/3;x5 = (x4+x5)/3;x1 = x5+x1;
int x1 = 6; int x2 = 7; int x3 = 8; int x4 = 9; int x5 = 10; x1 = x1/3; x5 = x5+x1; x2 = (x1+x2)/3; x1 = x2+x1; x3 = (x2+x3)/3; x2 = x3+x2; x4 = (x3+x4)/3; x3 = x4+x3; x5 = (x4+x5)/3; x4 = x5+x4; x1 = x5+x1; cout << x1 << " " << x2 << " " << x3 << " " <<x4<<" "<<x5<<endl;这样对了

全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,因此在此就以n个数字的排列为例说明排列的生 ...
全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,因此在此就以n个数字的排列为例说明排列的生成法。
n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外,都有一个后继;除第一个排列外,都有一个前驱。每个排列的后继都可以从 它 的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。
全排列的生成法通常有以下几种:
字典序法
递增进位数制法
递减进位数制法
邻位交换法
递归类算法
1.字典序法
字典序法中,对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是54321。
字典序算法如下:
设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
3)对换pi,pk
4)再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个下一个排列。
例如839647521是数字1~9的一个排列。从它生成下一个排列的步骤如下:
自右至左找出排列中第一个比右边数字小的数字4 839647521
在该数字后的数字中找出比4大的数中最小的一个5 839647521
将5与4交换 839657421
将7421倒转 839651247
所以839647521的下一个排列是839651247。
2.递增进位数制法
在递增进位制数法中,从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数,则排列的中介数就是对应的排列k1 ...... ki...... kn-1。
例如排列839647521的中介数是72642321,7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。
中介数是计算排列的中间环节。已知一个排列,要求下一个排列,首先确定其中介数,一个排列的后继,其中介数是原排列中介数加1,需要注意的是,如果中介数的末位kn-1+1=2,则要向前进位,一般情形,如果ki+1=n-i+1,则要进位,这就是所谓的递增进位制。例如排列839647521的中介数是72642321,则下一个排列的中介数是67342221+1=67342300(因为1+1=2,所以向前进位,2+1=3,又发生进位,所以下一个中介数是67342300)。
得到中介数后,可根据它还原对应得排列。
算法如下:
中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数,因此,要按k1、k2、......、kn-1的值从右向左确定n、n-1、......、2的位置,并逐个放置在排列中:i放在右起的ki+1位,如果某位已放有数字,则该位置不算在内,最后一个空位放1。
因此从67342300可得到排列849617523,它就是839647521的后一个排列。因为9最先放置,k1=6,9放在右起第7位,空出6个空位,然后是放8,k2=7,8放在右起第8位,但9占用一位,故8应放在右起第9位,余类推。
3.递减进位制数法
在递增进位制数法中,中介数的最低位是逢2进1,进位频繁,这是一个缺点。把递增进位制数翻转,就得到递减进位制数。
839647521的中介数是67342221(k1k2...kn-1),倒转成为12224376(kn-1...k2k1),这是递减进位制数的中介数:ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p,p的下一个排列的中介数定义为p的中介数加1。例如p=839647521,p的中介数为12224376,p的下一个排列的中介数为12224376+1=12224377,由此得到p的下一个排列为893647521。
给定中介数,可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中,可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下:
1)如果p(i)=n且i<>n,则p(i)与p(i-1)交换
2)如果p(n)=n,则找出一个连续递减序列9、8、......、i,将其从排列左端删除,再以相反顺序加在排列右端,然后将i-1与左边的数字交换
例如p=893647521的下一个排列是983647521。求983647521的下一个排列时,因为9在最左边且第2位为8,第3位不是7,所以将8和9从小到大排于最右端364752189,再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列,只需要将9876从小到大排到最右端并将5与其左方数字3对调,得到534216789。
4.邻位对换法
邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例,将最后的元素4逐次与前面的元素交换,可以生成4个新排列:
1 2 3 4 1 2 4 3 1 4 2 3 4 1 2 3
然后将最后一个排列的末尾的两个元素交换,再逐次将排头的4与其后的元素交换,又生成四个新排列:
4 1 3 2 1 4 3 2 1 3 4 2 1 3 2 4
再将最后一个排列的末尾的两个元素交换,将4从后往前移:
3 1 2 4 3 1 4 2 3 4 1 2 4 3 1 2
如此循环既可求出全部排列。
5.元素增值法(n进制法)
1)从原始排列p=p1p2......pn开始,第n位加n-1,如果该位的值超过n,则将它除以n,用余数取代该位,并进位(将第n-1位加1)
2)再按同样方法处理n-1位,n-2位,......,直至不再发生进位为止,处理完一个排列就产生了一个新的排列
3)将其中有相同元素的排列去掉
4)当第一个元素的值>n则结束
以3个数1、2、3的排列为例:原始排列是1 2 3,从它开始,第3个元素是3,3+2=5,5 Mod 3=2,第2个元素是2,2+1=3,所以新排列是1 3 2。通过元素增值,顺序产生的排列是:1 2 3,1 3 2,2 1 1,2 1 3,2 2 2,2 3 1,2 3 3,3 1 2,3 2 1
有下划线的排列中存在重复元素,丢弃,余下的就是全部排列。
6.递归类算法
全排列的生成方法用递归方式描述比较简洁,实现的方法也有多种。
1)回溯法
回溯法通常是构造一颗生成树。以3个元素为例;树的节点有个数据,可取值是1、2、3。如果某个为0,则表示尚未取值。
初始状态是(0,0,0),第1个元素值可以分别挑选1,2,3,因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值,如此反复进行,一旦出现新结点的3个数据全非零,那就找到了一种全排列方案。当尝试了所有可能方案,即获得了问题的解答。
2)递归算法
如果用P表示n个元素的排列,而Pi表示不包含元素i的排列,(i)Pi表示在排列Pi前加上前缀i的排列,那么,n个元素的排列可递归定义为:
如果n=1,则排列P只有一个元素i
如果n>1,则排列P由排列(i)Pi构成(i=1、2、....、n-1)。
根据定义,容易看出如果已经生成了k-1个元素的排列,那么,k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1,对与个元素而言,p1是2 3和3 2,在每个排列前加上1即生成1 2 3和1 3 2两个新排列,p2和p3则是1 3、3 1和1 2、2 1,按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。
3)循环移位法
如果已经生成了k-1个元素的排列,则在每个排列后添加元素k使之成为k个元素的排列,然后将每个排列循环左移(右移),每移动一次就产生一个新的排列。
例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3,将它循环左移可再生成新排列2 3 1、3 1 2,同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。


铜陵县18718156877: 求用 free pascal 编一程序、 -
蒲帝合贝: var a,b,c:longint; p,s:double;begin readln(a,b,c); if (a+b<=c)or(b+c<=a)or(c+a<=b) then writeln('no answer')else begin p:=(a+b+c)/2; s:=sqrt(p*(p-...

铜陵县18718156877: 求一个简单的free pascal程序 -
蒲帝合贝: var s:string; begin write('please write your name:'); readln(s); writeln(s,' is a pig.'); readln; end.

铜陵县18718156877: 求Free Pascal IDE的一个简单程序代码 -
蒲帝合贝: Var a, b, he, cha, ji, shang : Integer; Begin For a := 1 To 100 Do For b := a To 100 Do { 为避免重复,也为了节省时间,假定b是相对大数. } Begin If NOT ((a MOD b = 0) OR (b MOD a = 0)) Then Continue; { 两数不能整除就继续下一循环 } he := ...

铜陵县18718156877: 用free pascal编写一个小程序 -
蒲帝合贝: 用数组:var a:array[1..3] of longint; i,j,t:longint; begin for i:=1 to 3 do read(a[i]); for i:=1 to 2 do for j:=i+1 to 3 do if a[i]>a[j] then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; end; for i:=1 to 3 do write(a[i],' '); end. 不用数组的:var a,b,c,t:longint;begin readln(a,b,c); if a>...

铜陵县18718156877: free pascal如何设置???????????
蒲帝合贝: fp一般装在c盘pp目录下面,打开bin,再打开唯一的一个文件夹,运行fp.exe就可以编程了. 可以在fp.exe上单击右键,下拉菜单中选择"属性".里面有关于字体,字母颜色,中文兼容性的设置(以后你编中文程序有用).

铜陵县18718156877: 请写一个FREE PASCAL程序, 只要输入N值,便输出实心三角形.
蒲帝合贝: 很简单啊,注意场宽就好了 var n,i,j:longint; begin readln(n); for i:=1 to n do begin for j:=1 to n-i do write(' '); for j:=1 to i do write('* '); writeln; end; end. 具体的空格的话和我联系,我可以改

铜陵县18718156877: 谁可以帮我用FREE PASCAL 写一个程序
蒲帝合贝: 我编了一个,验证到n. program gdbh; var n,i,j:longint; w:boolean; function bz(q:longint):boolean; var i,j:longint; begin for i:=2 to q do begin bz:=true; for j:=2 to trunc(sqrt(i)); if i mod j=0 then bz:=false; end; end; begin readln(n); i:=6; repeat w:=true; for ...

铜陵县18718156877: 求解:Free Pascal编程 -
蒲帝合贝: var n,i,k:longint; a:array[1..maxint] of longint; function zx(x,y:longint):longint; var a,r,temp:longint; begin a:=x*y; if x>y then begin temp:=x ;x:=y;y:=temp; end; r:=x mod y; while r0 do begin x:=y; y:=r; r:=x mod y; end; zx:=a div y; end; begin read(n); for i:=1...

铜陵县18718156877: Free Pascal 编程 急需啊!!!
蒲帝合贝: 第一个program prog1;var i, n: integer; s: real;begin s := 0.0; readln(n); for i := 1 to n do s := s + 1 / i; writeln(s:10:3);end.第二个program prog1;var n: integer; s: real;begin readln(n); if (n <= 10) then s := 2.5 else s := 2.5 + (n - 10) * 1.5; writeln(s:10:2);end.

铜陵县18718156877: 请帮我做一下下面几个freePascal程序
蒲帝合贝: 下边是我写的 没测试过 有错的估计就是少个什么标点吧.. (1). 读入然后输出就行 用length(s)函数 求最大长度 var s:string; i:longint; begin readln(s); for i:=length(s)-1 downto 1 do write(s[i]); writeln; end; (2). val(s,a,b):是指将字符串S转变成a,...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网