Pascal Programs from Algorithms 2nd edition Copyright 1988. Addison-Wesley Publishing Company, Inc. All Rights Reserved. -------------------------------- CHAPTER 1 Introduction -------------------------------- CHAPTER 2 Pascal program euclid(input,output); var x,y: integer; function gcd(u,v: integer): integer; var t: integer; begin repeat if u0) and (y>0) then writeln(x,y,gcd(x,y)) end; end. -------------------------------- CHAPTER 3 Elementary Data Structures program primes(input,output); const N=1000; var a: array[1..N] of boolean; i,j: integer; begin a[1]:=false; for i:=2 to N do a[i]:=true; for i:=2 to N div 2 do for j:=2 to N div i do a[i*j]:=false; for i:=1 to N do if a[i] then write(i:4); end. type link =^node; node = record key: integer; next: link end; var head,z,t: link; procedure listinitialize; begin new(head); new(z); head^.next:=z; z^.next:=z end; procedure deletenext(t: link); begin t^.next:=t^.next^.next; end; procedure insertafter(v: integer; t: link); var x: link; begin new(x); x^.key:=v; x^.next:=t^.next; t^.next:=x end; program josephus(input,output); type link =^node; node = record key: integer; next: link end; var i,N,M: integer; t,x: link; begin read(N,M); new(t); t^.key:=1; x:=t; for i:=2 to N do begin new(t^.next); t:=t^.next; t^.key:=i end; t^.next:=x; while t<>t^.next do begin for i:=1 to M-1 do t:=t^.next; write(t^.next^.key); x:=t^.next; t^.next:=t^.next^.next; dispose(x); end; writeln(t^.key); end. var key,next: array[0..N] of integer; x,head,z: integer; procedure listinitialize; begin head:=0; z:=1; x:=1; next[head]:=z; next[z]:=z end; procedure deletenext(t: integer); begin next[t]:=next[next[t]] end; procedure insertafter(v: integer; t: integer); begin x:=x+1; key[x]:=v; next[x]:=next[t]; next[t]:=x end; push(5); push(9); push(8); push(pop+pop); push(4); push(6); push(pop*pop); push(pop*pop); push(7); push(pop+pop); push(pop*pop); writeln(pop); type link=^node; node= record key: integer; next: link end; var head,z: link; procedure stackinit; begin new(head); new(z); head^.next:=z; z^.next:=z end; procedure push(v: integer); var t: link; begin new(t); t^.key:=v; t^.next:=head^.next; head^.next:=t end; function pop: integer; var t: link; begin t:=head^.next; pop:=t^.key; head^.next:=t^.next; dispose(t) end; function stackempty: boolean; begin stackempty:=(head^.next=z) end; stackinit; repeat repeat read(c) until c<>' '; if c =')' then write(chr(pop)); if c ='+' then push(ord(c)); if c ='*' then push(ord(c)); while (c>='0') and (c<='9') do begin write(c); read(c) end; if c<>'(' then write (' '); until eoln; stackinit; repeat x:=0; repeat read(c) until c<>' '; if c ='*' then x:=pop*pop; if c ='+' then x:=pop+pop; while (c>='0') and (c<='9') do begin x:=10*x+(ord(c)-ord('0')); read(c) end; push(x); until eoln; writeln(pop); const maxP=100; var stack: array[0..maxP] of integer; p: integer; procedure push(v: integer); begin stack[p]:=v; p:=p+1 end; function pop: integer; begin p:=p-1; pop:=stack[p] end; procedure stackinit; begin p:=0 end; function stackempty: boolean; begin stackempty:=(p<=0) end; const max=100; var queue: array[0..max] of integer; head,tail: integer; procedure put(v: integer); begin queue[tail]:=v; tail:=tail+1; if tail>max then tail:=0 end; function get: integer; begin get:=queue[head]; head:=head+1; if head>max then head:=0 end; procedure queueinitialize; begin head:=0; tail:=0 end; function queueempty: boolean; begin queueempty:=(head=tail) end; -------------------------------- CHAPTER 4 Trees type link=^node; node=record info: char; l,r: link end; var x,z: link; c: char; begin stackinit; new(z); z^.l:=z; z^.r:=z; repeat repeat read(c) until c<>' '; new(x); x^.info:=c; if (c='*') or (c='+') then begin x^.r:=pop; x^.l:=pop end else begin x^.r:=z; x^.l:=z end; push(x) until eoln; procedure traverse(t: link); begin push(t); repeat t:=pop; visit(t); if t<>z then push(t^.r); if t<>z then push(t^.l); until stackempty; end; procedure traverse(t: link); begin put(t); repeat t:=get; visit(t); if t<>z then put(t^.l); if t<>z then put(t^.r); until queueempty; end; -------------------------------- CHAPTER 5 Recursion function factorial(N: integer): integer; begin if N=0 then factorial:=1 else factorial:=N*factorial(N-1); end; function fibonacci(N: integer): integer; begin if N<=1 then fibonacci:=1 else fibonacci:=fibonacci(N-1)+fibonacci(N-2); end; procedure fibonacci; const max=25; var i: integer; F: array[0..max] of integer; begin F[0]:=1; F[1]:=1; for i:=2 to max do F[i]:=F[i-1]+F[i-2] end; procedure rule(l,r,h: integer); var m: integer; begin if h>0 then begin m:=(l+r) div 2; mark(m,h); rule(l,m,h-1); rule(m,r,h-1) end end; procedure rule(l,r,h: integer); var i,j: integer; begin j:=1; for i:=1 to h do begin for x:=0 to (l+r) div j do mark(l+j+x*(j+j),i); j:=j+j; end; end; procedure star(x,y,r: integer); begin if r>0 then begin star(x-r,y+r,r div 2); star(x+r,y+r,r div 2); star(x-r,y-r,r div 2); star(x+r,y-r,r div 2); box(x,y,r); end end; procedure traverse(t: link); begin if t<>z then begin traverse(t^.l); visit(t); traverse(t^.r) end end; procedure visit(t: link); begin x:=x+1; t^.x:=x; t^.y:=y end; procedure traverse(t: link); begin y:=y+1; if t<>z then begin traverse(t^.l); visit(t); traverse(t^.r) end y:=y-1; end; procedure traverse(t: link); begin if t<>z then begin visit(t); traverse(t^.l); traverse(t^.r) end end; procedure traverse(t: link); label 0,1; begin 0: if t=z then goto 1; visit(t); traverse(t^.l); t:=t^.r; goto 0; 1: end; procedure traverse(t: link); label 0,1,2,3; begin 0: if t=z then goto 1; visit(t); push(t); t:=t^.l; goto 0; 3: t:=t^.r; goto 0; 1: if stackempty then goto 2; t:=pop; goto 3; 2: end; procedure traverse(t: link); label 0,2; begin 0: while t<>z do begin visit(t); push(t^.r); t:=t^.l end; if stackempty then goto 2; t:=pop; goto 0; 2: end; procedure traverse(t: link); begin push(t); repeat t:=pop; while t<>z do begin visit(t); push(t^.r); t:=t^.l end; until stackempty; end; procedure traverse(t: link); begin push(t); repeat t:=pop; if t<>z then begin visit(t); push(t^.r); push(t^.l); end; until stackempty; end; procedure traverse(t: link); begin push(t); repeat t:=pop; visit(t); if t^.r<>z then push(t^.r); if t^.l<>z then push(t^.l); until stackempty; end; -------------------------------- CHAPTER 6 Analysis of Algorithms -------------------------------- CHAPTER 7 Implementation of Algorithms -------------------------------- CHAPTER 8 Elementary Sorting Methods program threesort(input,output); const maxN=100; var a: array[1..maxN] of integer; N,i: integer; procedure sort3; var t: integer; begin if a[1]>a[2] then begin t:=a[1]; a[1]:=a[2]; a[2]:=t end; if a[1]>a[3] then begin t:=a[1]; a[1]:=a[3]; a[3]:=t end; if a[2]>a[3] then begin t:=a[2]; a[2]:=a[3]; a[3]:=t end; end; begin readln(N); for i:=1 to N do read(a[i]); if N=3 then sort3; for i:=1 to N do write(a[i]); writeln end. procedure selection; var i,j,min,t: integer; begin for i:=1 to N-1 do begin min:=i; for j:=i+1 to N do if a[j]v do begin a[j]:=a[j-1]; j:=j-1 end; a[j]:=v end end; procedure bubble; var i,j,t: integer; begin for i:=N downto 1 do for j:=2 to i do if a[j-1]>a[j] then begin t:=a[j-1]; a[j-1]:=a[j]; a[j]:=t end end; procedure insertion; var i,j,v: integer; begin for i:=1 to N do p[i]:=i; for i:=2 to N do begin v:=p[i]; j:=i; while a[p[j-1]]>a[v] do begin p[j]:=p[j-1]; j:=j-1 end; p[j]:=v end end; procedure insitu; var i,j,k,t: integer; begin for i:=1 to N do if p[i]<>i then begin t:=a[i]; k:=i; repeat j:=k; a[j]:=a[p[j]]; k:=p[j]; p[j]:=j; until k=i; a[j]:=t end; end; procedure shellsort; label 0; var i,j,h,v: integer; begin h:=1; repeat h:=3*h+1 until h>N; repeat h:=h div 3; for i:=h+1 to N do begin v:=a[i]; j:=i; while a[j-h]>v do begin a[j]:=a[j-h]; j:=j-h; if j<=h then goto 0 end; 0: a[j]:=v end until h=1; end; for j:=0 to M-1 do count[j]:=0; for i:=1 to N do count[a[i]]:=count[a[i]]+1; for j:=1 to M-1 do count[j]:=count[j-1]+count[j]; for i:=N downto 1 do begin b[count[a[i]]]:=a[i]; count[a[i]]:=count[a[i]]-1 end; for i:=1 to N do a[i]:=b[i]; { -------------------------------- CHAPTER 9 Quicksort procedure quicksort(l,r: integer); var i: integer; begin if r>l then begin i:=partition(l,r); quicksort(l,i-1); quicksort(i+1,r) end end; procedure quicksort(l,r: integer); var v,t,i,j: integer; begin if r>l then begin v:=a[r]; i:=l-1; j:=r; repeat repeat i:=i+1 until a[i]>=v; repeat j:=j-1 until a[j]<=v; t:=a[i]; a[i]:=a[j]; a[j]:=t; until j<=i; a[j]:=a[i]; a[i]:=a[r]; a[r]:=t; quicksort(l,i-1); quicksort(i+1,r) end end; procedure quicksort; var t,i,l,r: integer; begin l:=1; r:=N; stackinit; push(l); push(r); repeat if r>l then begin i:=partition(l,r); if (i-l)>(r-i) then begin push(l); push(i-1); l:=i+1 end else begin push(i+1); push(r); r:=i-1 end; end else begin r:=pop; l:=pop end; until stackempty; end; procedure select(l,r,k: integer); var i; begin if r>l then begin i:=partition(l,r); if i>l+k-1 then select(l,i-1,k); if il do begin v:=a[r]; i:=l-1; j:=r; repeat repeat i:=i+1 until a[i]>=v; repeat j:=j-1 until a[j]<=v; t:=a[i]; a[i]:=a[j]; a[j]:=t; until j<=i; a[j]:=a[i]; a[i]:=a[r]; a[r]:=t; if i>=k then r:=i-1; if i<=k then l:=i+1; end; end; -------------------------------- CHAPTER 10 Radix Sorting procedure radixexchange(l,r,b: integer); var t,i,j: integer; begin if (r>l) and (b>=0) then begin i:=l; j:=r; repeat while (bits(a[i],b,1)=0) and (ia[max] then max:=j; remove:=a[max]; a[max]:=a[N]; N:=N-1; end; procedure upheap(k: integer); var v: integer; begin v:=a[k]; a[0]:=maxint; while a[k div 2]<=v do begin a[k]:=a[k div 2]; k:=k div 2 end; a[k]:=v end; procedure insert(v: integer); begin N:=N+1; a[N]:=v; upheap(N) end; procedure downheap(k: integer); label 0; var i,j,v: integer; begin v:=a[k]; while k<=N div 2 do begin j:=k+k; if j=a[j] then goto 0; a[k]:=a[j]; k:=j; end; 0: a[k]:=v end; function remove: integer; begin remove:=a[1]; a[1]:=a[N]; N:=N-1; downheap(1); end; function replace(v: integer):integer; begin a[0]:=v; downheap(0); replace:=a[0]; end; N:=0; for k:=1 to M do insert(a[k]); for k:=M downto 1 do a[k]:=remove; procedure heapsort; var k,t: integer; begin N:=M; for k:=M div 2 downto 1 do downheap(k); repeat t:=a[1]; a[1]:=a[N]; a[N]:=t; N:=N-1; downheap(1) until N<=1; end; procedure pqconstruct; var k: integer; begin N:=M; for k:=1 to N do begin p[k]:=k; q[k]:=k end; for k:=M div 2 downto 1 do pqdownheap(k); end; procedure pqdownheap(k: integer); label 0; var j,v: integer; begin v:=p[k]; while k<= N div 2 do begin j:=k+k; if j=a[p[j]] then goto 0; p[k]:=p[j]; q[p[j]]:=k; k:=j; end; 0: p[k]:=v; q[v]:=k end; -------------------------------- CHAPTER 12 Mergesort i:=1; j:=1; a[M+1]:=maxint; b[N+1]:=maxint; for k:=1 to M+N do if a[i]0 then begin m:=(r+l) div 2; mergesort(l,m); mergesort(m+1,r); for i:=m downto l do b[i]:=a[i]; for j:=m+1 to r do b[r+m+1-j]:=a[j]; for k:=l to r do if b[i]z do begin c:=c^.next; b:=b^.next; b:=b^.next end; b:=c^.next; c^.next:=z; mergesort:=merge(mergesort(a),mergesort(b)); end; end; function mergesort(c: link): link; var a,b,head,todo,t: link; i,N: integer; begin N:=1; new(head); head^.next:=c; repeat todo:=head^.next; c:=head; repeat t:=todo; a:=t; for i:=1 to N-1 do t:=t^.next; b:=t^.next; t^.next:=z; t:=b; for i:=1 to N-1 do t:=t^.next; todo:=t^.next; t^.next:=z; c^.next:=merge(a,b); for i:=1 to N+N do c:=c^.next until todo=z; N:=N+N; until a=head^.next; mergesort:=head^.next end; -------------------------------- CHAPTER 13 External Sorting -------------------------------- CHAPTER 14 Elementary Searching Methods type node= record key,info: integer end; var a: array[0..maxN] of node; N: integer; procedure initialize; begin N:=0 end; function seqsearch(v: integer; x: integer): integer; begin a[N+1].key:=v; if x<=N then repeat x:=x+1 until v=a[x].key; seqsearch:=x end; function seqinsert(v: integer): integer; begin N:=N+1; a[N].key:=v; seqinsert:=N; end; type link=^node; node= record key,info: integer; next: link end; var head,t,z: link; i: integer; procedure initialize; begin new(z); z^.next:=z; new(head); head^.next:=z; end; function listsearch(v: integer; t: link): link; begin z^.key:=v; repeat t:=t^.next until v<=t^.key; if v=t^.key then listsearch:=t else listsearch:=z end; function listinsert(v: integer; t: link): link; var x: link; begin z^.key:=v; while t^.next^.keyr); if v=a[x].key then binarysearch:=x else binarysearch:=N+1 end; type link=^node; node=record key,info: integer; l,r: link end; var t,head,z: link; function treesearch(v: integer; x: link): link; begin z^.key:=v; repeat if vz then begin treeprint(x^.l); printnode(x); treeprint(x^.r) end end; procedure treedelete(t,x: link); var p,c: link; begin repeat p:=x; if t^.keyz do c:=c^.l; x:=c^.l; c^.l:=x^.r; x^.l:=t^.l; x^.r:=t^.r end; if t^.key(vmaxint do x:=(x+1) mod M; a[x].key:=v; hashinsert:=x; end; -------------------------------- CHAPTER 17 Radix Searching function digitalsearch(v: integer; x: link): link; var b: integer; begin z^.key:=v; b:=maxb; repeat if bits(v,b,1)=0 then x:=x^.l else x:=x^.r; b:=b-1; until v=x^.key; digitalsearch:=x end; function digitalinsert(v: integer; x: link): link; var p: link; b: integer; begin b:=maxb; repeat p:=x; if bits(v,b,1)=0 then x:=x^.l else x:=x^.r; b:=b-1; until x=z; new(x); x^.key:=v; x^.l:=z; x^.r:=z; if bits(v,b+1,1)=0 then p^.l:=x else p^.r:=x; digitalinsert:=x end; type link=^node; node= record key,info,b: integer; l,r: link end; var head,z: link; function patriciasearch(v: integer; x: link): link; var p: link; begin repeat p:=x; if bits(v,x^.b,1)=0 then x:=x^.l else x:=x^.r; until p^.b<=x^.b; patriciasearch:=x end; function patriciainsert(v: integer; x: link): link; label 0; var t,p: link; i: integer; begin t:=patriciasearch(v,x); if v=t^.key then goto 0; i:=maxb; while bits(v,i,1)=bits(t^.key,i,1) do i:=i-1; repeat p:=x; if bits(v,x^.b,1)=0 then x:=x^.l else x:=x^.r; until (x^.b<=i) or (p^.b<=x^.b); new(t); t^.key:=v; t^.b:=i; if bits(v,t^.b,1)=0 then begin t^.l:=t; t^.r:=x end else begin t^.r:=t; t^.l:=x end; if bits(v,p^.b,1)=0 then p^.l:=t else p^.r:=t; 0: patriciainsert:=t end; -------------------------------- CHAPTER 18 External Searching -------------------------------- CHAPTER 19 String Searching function brutesearch: integer; var i,j: integer; begin i:=1; j:=1; repeat if a[i]=p[j] then begin i:=i+1; j:=j+1 end else begin i:=i-j+2; j:=1 end; until (j>M) or (i>N); if j>M then brutesearch:=i-M else brutesearch:=i end; function kmpsearch: integer; var i,j: integer; begin i:=1; j:=1; initnext; repeat if (j=0) or (a[i]=p[j]) then begin i:=i+1; j:=j+1 end else begin j:=next[j] end; until (j>M) or (i>N); if j>M then kmpsearch:=i-M else kmpsearch:=i; end; procedure initnext; var i,j: integer; begin i:=1; j:=0; next[1]:=0; repeat if (j=0) or (p[i]=p[j]) then begin i:=i+1; j:=j+1; next[i]:=j end else begin j:=next[j] end; until i>=M; end; i:=0; 0: i:=i+1; 1: if a[i]<>'1' then goto 0; i:=i+1; 2: if a[i]<>'0' then goto 1; i:=i+1; 3: if a[i]<>'1' then goto 1; i:=i+1; 4: if a[i]<>'0' then goto 2; i:=i+1; 5: if a[i]<>'0' then goto 3; i:=i+1; 6: if a[i]<>'1' then goto 1; i:=i+1; 7: if a[i]<>'1' then goto 2; i:=i+1; 8: if a[i]<>'1' then goto 2; i:=i+1; search:=i-8; if p[j]<>p[i] then next[i]:=j else next[i]:=next[j]; function mischarsearch: integer; var i,j: integer; begin i:=M; j:=M; initskip; repeat if a[i]=p[j] then begin i:=i-1; j:=j-1 end else begin if M-j+1>skip[index(a[i])] then i:=i+M-j+1 else i:=i+skip[index(a[i])]; j:=M; end; until (j<1) or (i>N); mischarsearch:=i+1 end; function rksearch: integer; const q=33554393; d=32; var h1,h2,dM,i: integer; begin dM:=1; for i:=1 to M-1 do dM:=(d*dM) mod q; h1:=0; for i:=1 to M do h1:=(h1*d+index(p[i])) mod q; h2:=0; for i:=1 to M do h2:=(h2*d+index(a[i])) mod q; i:=1; while (h1<>h2) and (i<=N-M) do begin h2:=(h2+d*q-index(a[i])*dM) mod q; h2:=(h2*d+index(a[i+M])) mod q; i:=i+1; end; rksearch:=i; end; -------------------------------- CHAPTER 20 Pattern Matching function match(j: integer): integer; const scan=-1; var state,n1,n2: integer; begin dequeinit; put(scan); match:=j-1; state:=next1[0]; repeat if state=scan then begin j:=j+1; put(scan) end else if ch[state]=a[j] then put(next1[state]) else if ch[state]=' ' then begin n1:=next1[state]; n2:=next2[state]; push(n1); if n1<>n2 then push(n2) end; state:=pop; until (j>N) or (state=0) or (dequeempty); if state=0 then match:=j-1; end; -------------------------------- CHAPTER 21 Parsing procedure expression; begin term; if p[j]='+' then begin j:=j+1; expression end end; procedure term; begin factor; if (p[j]='(') or letter(p[j]) then term end; procedure factor; begin if p[j]='(' then begin j:=j+1; expression; if p[j]=')' then j:=j+1 else error end else if letter(p[j]) then j:=j+1 else error; if p[j]='*' then j:=j+1 end; procedure badexpression; begin if letter(p[j]) then j:=j+1 else begin badexpression; if p[j]<>'+' then error else begin j:=j+1; term end end end; function expression: integer; var t1,t2: integer; begin t1:=term; expression:=t1; if p[j]='+' then begin j:=j+1; state:=state+1; t2:=state; expression:=t2; state:=state+1; setstate(t2,' ',expression,t1); setstate(t2-1,' ',state,state); end; end; function term; var t: integer; begin term:=factor; if (p[j]='(') or letter(p[j]) then t:=term end; function factor; var t1,t2: integer; begin t1:=state; if p[j]='(' then begin j:=j+1; t2:=expression; if p[j]=')' then j:=j+1 else error end else if letter(p[j]) then begin setstate(state,p[j],state+1,state+1); t2:=state; j:=j+1; state:=state+1 end else error; if p[j]<>'*' then factor:=t2 else begin setstate(state,' ',state+1,t2); factor:=state; next1[t1-1]:=state; j:=j+1; state:=state+1; end; end; procedure matchall; begin j:=1; state:=1; next1[0]:=expression; setstate(state,' ',0,0); for i:=1 to N-1 do if match(i)>=i then writeln(i); end; -------------------------------- CHAPTER 22 File Compression for i:=0 to 26 do count[i]:=0; for i:=1 to M do count[index(a[i])]:=count[index(a[i])]+1; N:=0; for i:=0 to 26 do if count[i]<>0 then begin N:=N+1; heap[N]:=i end; for k:=N downto 1 do pqdownheap(k); repeat t:=heap[1]; heap[1]:=heap[N]; N:=N-1; pqdownheap(1); count[26+N]:=count[heap[1]]+count[t]; dad[t]:=26+N; dad[heap[1]]:=-26-N; heap[1]:=26+N; pqdownheap(1); until N=1; dad[26+N]:=0; for k:=0 to 26 do if count[k]=0 then begin code[k]:=0; len[k]:=0 end else begin i:=0; j:=1; t:=dad[k]; x:=0; repeat if t<0 then begin x:=x+j; t:=-t end; t:=dad[t]; j:=j+j; i:=i+1 until t=0; code[k]:=x; len[k]:=i; end; for j:=1 to M do for i:=len[index(a[j])] downto 1 do write(bits(code[index(a[j])],i-1,1):1); -------------------------------- CHAPTER 23 Cryptology -------------------------------- CHAPTER 24 Elementary Geometric Methods type point = record x,y: integer end; line = record p1,p2: point end; var polygon: array[0..Nmax] of point; function ccw(p0,p1,p2: point): integer; var dx1,dx2,dy1,dy2: integer; begin dx1:=p1.x-p0.x; dy1:=p1.y-p0.y; dx2:=p2.x-p0.x; dy2:=p2.y-p0.y; if dx1*dy2>dy1*dx2 then ccw:=1; if dx1*dy2=(dx2*dx2+dy2*dy2) then ccw:=0 else ccw:=1; end; end; function intersect(l1,l2: line): boolean; begin intersect:=((ccw(l1.p1,l1.p2,l2.p1)*ccw(l1.p1,l1.p2,l2.p2))<=0) and ((ccw(l2.p1,l2.p2,l1.p1)*ccw(l2.p1,l2.p2,l1.p2))<=0); end; function theta(p1,p2: point): real; var dx,dy,ax,ay: integer; t: real; begin dx:=p2.x-p1.x; ax:=abs(dx); dy:=p2.y-p1.y; ay:=abs(dy); if (dx=0) and (dy=0) then t:=0 else t:=dy/(ax+ay); if dx<0 then t:= 2-t else if dy<0 then t:=4+t; theta:=t*90.0; end; function inside(t: point): boolean; var count,i,j: integer; lt,lp: line; begin count:=0; j:=0; p[0]:=p[N]; p[N+1]:=p[1]; lt.p1:=t; lt.p2:=t; lt.p2.x:=maxint; for i:=1 to N do begin lp.p1:=p[i]; lp.p2:=p[i]; if not intersect(lp,lt) then begin lp.p2:=p[j]; j:=i; if intersect(lp,lt) then count:=count+1; end; end; inside:=((count mod 2)=1); end; -------------------------------- CHAPTER 25 Finding the Convex Hull function wrap: integer; var i,min,M: integer; minangle,v: real; t: point; begin min:=1; for i:=2 to N do if p[i].yv then if theta(p[M],p[i])p[min].x) then min:=i; t:=p[1]; p[1]:=p[min]; p[min]:=t; shellsort; p[0]:=p[N]; M:=3; for i:=4 to N do begin while ccw(p[M],p[M-1],p[i])>=0 do M:=M-1; M:=M+1; t:=p[M]; p[M]:=p[i]; p[i]:=t; end; grahamscan:=M; end; -------------------------------- CHAPTER 26 Range Searching type interval = record x1,x2: integer end; procedure treerange(t: link; int: interval); var tx1,tx2: boolean; begin if t<>z then begin tx1:=t^.key>=int.x1; tx2:=t^.key<=int.x2; if tx1 then treerange(t^.l,int); if tx1 and tx2 then {t^.key is within the range} if tx2 then treerange(t^.r,int); end end; const maxG=20; type link=^node; node=record p: point; next: link end; var grid: array[0..maxG,0..maxG] of link; size: integer; z: link; procedure preprocess; procedure insert(p: point); var t: link; begin new(t); t^.p:=p; t^.next:=grid[p.x div size,p.y div size]; grid[p.x div size,p.y div size]:=t; end; begin new(z); size:=1; while size*sizez do begin if insiderect(t^.p, rect) then {point t^.p is within the range} t:=t^.next end end end; type link=^node; node=record p: point; l,r: link end; var t,head,z: link; procedure treeinsert(p: point; t: link); var f: link; d,td: boolean; begin d:=true; repeat if d then td:=p.xz then begin tx1:=rect.x1y1 then bstinsert(N,y2,hy); until eof; end; procedure scan(next: link); var t,x1,x2,y1,y2: integer; int: interval; begin if next<>z then begin scan(next^.l); x1:=lines[next^.info].p1.x; y1:=lines[next^.info].p1.y; x2:=lines[next^.info].p2.x; y2:=lines[next^.info].p2.y; if x2z^.p.y) and (p2.y<>z^.p.y) then begin dist:=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); if distz do begin if val[t^.v]=0 then visit(t^.v); t:=t^.next end end; begin id:=0; for k:=1 to V do val[k]:=0; for k:=1 to V do if val[k]=0 then visit(k) end; procedure visit(k: integer); var t: integer; begin id:=id+1; val[k]:=id; for t:=1 to V do if a[k,t] then if val[t]=0 then visit(t); end; procedure listdfs; var id,k: integer; val: array[1..maxV] of integer; procedure visit(k: integer); var t: link; begin push(k); repeat k:=pop; id:=id+1; val[k]:=id; t:=adj[k]; while t<>z do begin if val[t^.v]=0 then begin push(t^.v); val[t^.v]:=-1 end; t:=t^.next end until stackempty end; begin id:=0; stackinit; for k:=1 to V do val[k]:=0; for k:=1 to V do if val[k]=0 then visit(k) end; procedure listbfs; var id,k: integer; val: array[1..maxV] of integer; procedure visit(k: integer); var t: link; begin put(k); repeat k:=get; id:=id+1; val[k]:=id; t:=adj[k]; while t<>z do begin if val[t^.v]=0 then begin put(t^.v); val[t^.v]:=-1 end; t:=t^.next end until queueempty end; begin id:=0; queueinitialize; for k:=1 to V do val[k]:=0; for k:=1 to V do if val[k]=0 then visit(k) end; -------------------------------- CHAPTER 30 Connectivity function visit(k: integer): integer; var t: link; m,min: integer; begin id:=id+1; val[k]:=id; min:=id; t:=adj[k]; while t<>z do begin if val[t^.v]=0 then begin m:=visit(t^.v); if m=val[k] then write(name(k)); end else if val[t^.v]0 do i:=dad[i]; j:=y; while dad[j]>0 do j:=dad[j]; if union and (i<>j) then dad[j]:=i; find:=(i<>j) end; function find(x,y: integer; union: boolean): boolean; var i,j,t: integer; begin i:=x; while dad[i]>0 do i:=dad[i]; j:=y; while dad[j]>0 do j:=dad[j]; while dad[x]>0 do begin t:=x; x:=dad[x]; dad[t]:=i end; while dad[y]>0 do begin t:=y; y:=dad[y]; dad[t]:=j end; if union and (i<>j) then if dad[j]j) end; -------------------------------- CHAPTER 31 Weighted Graphs procedure listpfs; var id,k: integer; val: array[1..maxV] of integer; procedure visit(k: integer); var t: link; begin if pqupdate(k,unseen) then dad[k]:=0; repeat id:=id+1; k:=pqremove; val[k]:=-val[k]; if val[k]=unseen then val[k]:=0; t:=adj[k]; while t<>z do begin if val[t^.v]<0 then if pqupdate(t^.v,priority) then begin val[t^.v]:=-(priority); dad[t^.v]:=k end; t:=t^.next end until pqempty end; begin id:=0; pqinitialize; for k:=1 to V do val[k]:=-unseen; for k:=1 to V do if val[k]=-unseen then visit(k) end; program kruskal(input,output); const maxV=50; maxE=2500; type edge=record v1,v2,w: integer end; var i,j,m,x,y,V,E: integer; edges: array[0..maxE] of edge; begin readln(V,E); for j:=1 to E do begin readln(c,d,edges[j].w); edges[j].v1:=index(c); edges[j].v2:=index(d); end; findinit; pqconstruct; i:=0; repeat m:=pqremove; x:=edges[m].v1; y:=edges[m].v2; if find(x,y,true) then begin edgefound(x,y); i:=i+1 end until pqempty or (i=V-1); end. procedure matrixpfs; var k,min,t: integer; begin for k:=1 to V do begin val[k]:=-unseen; dad[k]:=0 end; val[0]:=-(unseen+1); min:=1; repeat k:=min; val[k]:=-val[k]; min:=0; if val[k]=unseen then val[k]:=0; for t:=1 to V do if val[t]<0 then begin if (a[k,t]<>0) and (val[t]<-(priority) then begin val[t]:=-(priority); dad[t]:=k end; if val[t]>val[min] then min:=t; end until min=0; end; -------------------------------- CHAPTER 32 Directed Graphs for k:=1 to V do begin id:=0; for j:=1 to V do val[j]:=0; visit(k); writeln end; for y:=1 to V do for x:=1 to V do if a[x,y] then for j:=1 to V do if a[y,j] then a[x,j]:=true; for y:=1 to V do for x:=1 to V do if a[x,y]>0 then for j:=1 to V do if a[y,j]>0 then if (a[x,j]=0) or (a[x,y]+a[y,j]z do begin if val[t^.v]=0 then m:=visit(t^.v) else m:=val[t^.v]; if m0 then priority:=size[k,t]-flow[k,t] else priority:=-flow[k,t]; if priority>val[k] then priority:=val[k]; repeat matrixpfs(1,V); y:=V; x:=dad[V]; while x<>0 do begin flow[x,y]:=flow[x,y]+val[V]; flow[y,x]:=-flow[x,y]; y:=x; x:=dad[y] end until val[V]=1-maxint -------------------------------- CHAPTER 34 Matching for m:=1 to N do begin s:=m; repeat next[s]:=next[s]+1; w:=prefer[s,next[s]]; if rank[w,s]0.0) then begin t:=listadd(t,p^.c+q^.c,p^.j); p:=p^.next; q:=q^.next end else if p^.jabs(a[max,i]) then max:=j; for k:=i to N+1 do begin t:=a[i,k]; a[i,k]:=a[max,k]; a[max,k]:=t end; for j:=i+1 to N do for k:=N+1 downto i do a[j,k]:=a[j,k]-a[i,k]*a[j,i]/a[i,i]; end end; procedure substitute; var j,k: integer; t: real; begin for j:=N downto 1 do begin t:=0.0; for k:=j+1 to N do t:=t+a[j,k]*x[k]; x[j]:=(a[j,N+1]-t)/a[j,j] end end; for i:=1 to N-1 do begin a[i+1,N+1]:=a[i+1,N+1]-a[i,N+1]*a[i+1,i]/a[i,i]; a[i+1,i+1]:=a[i+1,i+1]-a[i,i+1]*a[i+1,i]/a[i,i] end; for j:=N downto 1 do x[j]:=(a[j,N+1]-a[j,j+1]*x[j+1])/a[j,j]; -------------------------------- CHAPTER 38 Curve Fitting procedure makespline; var i: integer; begin readln(N); for i:=1 to N do readln(x[i],y[i]); for i:=2 to N-1 do d[i]:=2*(x[i+1]-x[i-1]); for i:=1 to N-1 do u[i]:=x[i+1]-x[i]; for i:=2 to N-1 do w[i]:=6.0*((y[i+1]-y[i])/u[i]-(y[i]-y[i-1])/u[i-1]); p[1]:=0.0; p[N]:=0.0; for i:=2 to N-2 do begin w[i+1]:=w[i+1]-w[i]*u[i]/d[i]; d[i+1]:=d[i+1]-u[i]*u[i]/d[i] end; for i:=N-1 downto 2 do p[i]:=(w[i]-u[i]*p[i+1])/d[i]; end; function eval(v: real): real; var t: real; i: integer; function f(x: real): real; begin f:=x*x*x-x end; begin i:=0; repeat i:=i+1 until v<=x[i+1]; t:=(v-x[i])/u[i]; eval:=t*y[i+1]+(1-t)*y[i] +u[i]*u[i]*(f(t)*p[i+1]+f(1-t)*p[i])/6.0 end; for i:=1 to M do for j:=1 to M+1 do begin t:= 0.0; for k:=1 to N do t:=t+f[i,k]*f[j,k]; a[i,j]:=t; end; -------------------------------- CHAPTER 39 Integration for i:=N downto 1 do p[i]:=p[i-1]/i; p[0]:=0; function intrect(a,b: real; N: integer): real; var i: integer; w,r: real; begin r:=0; w:=(b-a)/N; for i:=1 to N do r:=r+w*f(a-w/2+i*w); intrect :=r; end; function inttrap(a,b: real; N: integer): real; var i: integer; w,t: real; begin t:=0; w:=(b-a)/N; for i:=1 to N do t:=t+w*(f(a+(i-1)*w)+f(a+i*w))/2; inttrap:=t; end; function intsimp(a,b: real; N: integer): real; var i: integer; w,s: real; begin s:=0; w:=(b-a)/N; for i:=1 to N do s:=s+w*(f(a+(i-1)*w)+4*f(a-w/2+i*w)+f(a+i*w))/6; intsimp:=s; end; function adapt(a,b: real): real; begin if abs(intsimp(a,b,10)-intsimp(a,b,5))=0 then if cost[i]<(cost[i-size[j]]+val[j]) then begin cost[i]:=cost[i-size[j]]+val[j]; best[i]:=j end; end; for i:=1 to N do for j:=i+1 to N do cost[i,j]:=maxint; for i:=1 to N do cost[i,i]:=0; for j:=1 to N-1 do for i:=1 to N-j do for k:=i+1 to i+j do begin t:=cost[i,k-1]+cost[k,i+j]+r[i]*r[k]*r[i+j+1]; if tp) and (k<>q) then a[j,k]:=a[j,k]-a[p,k]*a[j,q]/a[p,q]; for j:=0 to N do if j<>p then a[j,q]:=0; for k:=1 to M+1 do if k<>q then a[p,k]:=a[p,k]/a[p,q]; a[p,q]:=1 end; repeat q:=0; repeat q:=q+1 until (q=M+1) or (a[0,q]<0); p:=0; repeat p:=p+1 until (p=N+1) or (a[p,q]>0); for i:=p+1 to N do if a[i,q]>0 then if (a[i,M+1]/a[i,q])<(a[p,M+1]/a[p,q]) then p:=i; if (q