FOR I:=J+1 TO N+1 DO B[I]:=1; END; S:=0;
FOR I:=1 TO 1000 DO
④ ; ????s:=s+g[i] WRITELN(S);READLN; END.
模拟
存储空间的回收算法。设在内存中已经存放了若干个作业A,B,C,D。其余的空间为可用的(如图一中(a))。
此时,可用空间可用一个二维数组dk[1..100,1..2 ]表示,(如下表一中(a)),其中:dk[i,1]对应第i个可用空间首址,dk[i,2]对应第i个可用空间长度如上图中,dk:
0 100 100 300 500 0 50 100 100 0 50 100 100 300 500 10000 表一(a) 表一(b)
现某个作业释放一个区域,其首址为d,长度为L,此时将释放区域加入到可用空间表中。要求在加入时,若可用空间相邻时,则必须进行合并。因此出现下面的4种情况: (1)下靠,即回收区域和下面可用空间相邻,例如,d=80,L=20,此时成为表二中的(a)。 (2)上靠,例如,d=600,L=50,此时表成为表二中的(b)。
(3)上、下靠,例如,d=150,L=150,此时表成为表二中的(c)。 (4)上、下不靠,例如,d=430,L=20,此时表成为表二中的(d)。
100 80 300 50 50 100 20 100 70 100 100 100 300 500 50 100 150 300 100 500 300 100 430 500 表二(a)(下靠) 表二(b)(上靠) 表二(c)(上,下靠) 表二(d)(上,下不靠)
程序说明:对数组dk预置2个标志,即头和尾标志,成为表一中(b),这样可使算法简单,sp为dk表末地址。 程序清单:
VAR I,J,SP,D,L:INTEGER;
DK :ARRAY[0..100,1..2]OF INTEGER; BEGIN
READLN(SP); FOR I:=1 TO SP DO
READLN(DK[I,1],DK[I,2]);
DK[0,1]:=0;DK[0,2]:=0; ① ;
DK[SP,1]:=10000;DK[SP,2]:=0;READLN(D,L);I:=1; WHILE DK[I,1] IF(DK[I,1]+DK[I,2]=D)THEN {与前面的一段靠在一起} IF(D+L=DK[I+1,1])THEN {和后面的一段也靠在一起,即上下靠} BEGIN DK[I,2]:= ③ ; FOR J:=I+1 TO SP-1 DO {删除dk[i+1]} DK[J]:=DK[J+1]; SP:=SP-1; END ELSE DK[I,2]:=DK[I,2]+L {仅和前面靠} ELSE IF(D+L=DK[I+1,1])THEN {仅和后面靠} BEGIN DK[I+1,1]:= ④ ;DK[I+1,2]:=DK[I+1,2]+L END ELSE BEGIN {都不靠,插入} FOR J:=SP DOWNTO I+1 DO DK[J+1]:=DK[J]; ⑤ :=D; DK[I+1,2]:=L;SP:=SP+1; END; FOR I:=1 TO SP-1 DO WRITELN(DK[I,1]:4,DK[I,2]:4);READLN; END. 1、SP:=SP+1 2、I:=I-1 3、DK[I,2]+L+DK[I+1,2] 4、D 5、DK[I+1,1] Joseph 题目描述: 原始的Joseph问题的描述如下:有n个人围坐在一个圆桌周围,把这n个人依次编号为1,…,n。从编号是1的人开始报数,数到第m个人出列,然后从出列的下一个人重新开始 报数,数到第m个人又出列,…,如此反复直到所有的人全部出列为止。比如当n=6,m=5的时候,出列的顺序依次是5,4,6,2,3,1。 现在的问题是:假设有k个好人和k个坏人。好人的编号的1到k,坏人的编号是k+1到2k。我们希望求出m的最小值,使得最先出列的k个人都是坏人。 输入: 仅有的一个数字是k(0 < k <14)。 输出: 使得最先出列的k个人都是坏人的m的最小值。 输入样例: 4 输出样例: 30 程序: program program2; var i, k, m, start: longint; find: boolean; function check(remain: integer): boolean; {remain目前剩余人数} var result: integer; begin result:=( ① ) mod remain; {result这次出列的人的编号} if( ② )then begin start := result; check := true; {符合要求,为下一次做准备} end else check := false; {不符合要求} end; begin find := false; read(k); m := k; {枚举m} while ( ③ ) do begin find := true; start := 0; {人从0开始编号} for i := 0 to k-1 do {模拟k次出列} if( not check( ④ )) then begin find := false; break; {不符合要求,停止此次,直接枚举下一个m} end; inc(m); end; writeln( ⑤ ); end. ① start+m-1 ② result>=k (或者k<=result) ③ not find (或者 find=false) ④ 2*k-i ⑤ m-1 关键路径 设有一个工程网络如下图表示(无环路的有向图): 其中,顶点表示活动,①表示工程开始,⑤表示工程结束(可变,用N表示),边上的数字表示活动延续的时间。 如上图中,活动①开始5天后活动②才能开始工作,而活动③则要等①、②完成之后才能开始,即最早也要7天后才能工作。 在工程网络中,延续时间最长的路径称为关键路径。上图中的关键路径为:①—②—③—④—⑤共18天完成。 关键路径的算法如下: 1.数据结构:{重要定义} R[1..N,1..N]OF INTEGER; 表示活动的延续时间,若无连线,则用-1表示; EET[1..N] 表示活动最早可以开始的时间 ET[1..N] 表示活动最迟应该开始的时间 关键路径通过点J,具有如下的性质:EET[J]=ET[J] 2.约定: 结点的排列已经过拓扑排序,即序号前面的结点会影响序号后面结点的活动。 程序清单: VAR I,J,N,MAX,MIN,W,X,Y:INTEGER; R:ARRAY[1..20,1..20] OF INTEGER; EET,ET:ARRAY[1..20] OF INTEGER; BEGIN READLN(N) FOR I:=1 TO N DO FOR J:=1 TO N DO R[I,J]:=-1; READLN(X,Y,W);{输入从活动X到活动Y的延续时间,以0为结束} WHILE X<>0 DO BEGIN R[X,Y]:=W; ① END; EET[1]:=0;{认为工程从0天开始} FOR I:=2 TO N DO BEGIN MAX:=0;
相关推荐: