(* Gli autobus (IOI 1994) Copyright (C) 2000 Paolo Boldi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) program Ioi9422; (* Uno schedule Š una coppia dove s Š l'istante del primo passaggio e p Š la frequenza. Diremo che lo schedule Š ammissibile sse gli istanti s,s+p,s+2p,... sono registrati. Quanti sono gli schedule ammissibili? Notate che s, con s<=29 e s+1<=p<=59-s. Quindi sono 58+56+54+...+2, cioe' 2(1+2+...+29)=29*30=870. Gli schedule ammissibili vengono precalcolati (procedura ammissibili) e messi nell'array sch. Per ogni schedule viene anche calcolato (campo pass) il numero complessivo di passaggi che verrebbero registrati per quello schedule *) const maxbus=17; maxsch=870; nomefin='input-6.txt'; nomefout='myout-6.txt'; DEBUG=false; type schedule=record s,p,pass: byte; end; var rec: array [0..59] of byte; (* Numero passaggi all'istante 0,1... *) passaggi: word; (* Numero complessivo di passaggi *) nsch: word; (* Numero schedule ammissibili *) sch: array [1..maxsch] of schedule; (* Schedule ammissibili *) procedure inp; (* Lettura dell'input *) var f: text; i,j: integer; begin assign(f,nomefin); reset(f); read(f,passaggi); for i:=0 to 59 do rec[i]:=0; for i:=1 to passaggi do begin read(f,j); inc(rec[j]); end; close(f) end; function ammissibile(s: schedule; c: integer; var pass: byte): boolean; (* Guarda se lo schedule s Š ammissibile rispetto a rec. Inoltre, aggiunge c ad ogni elemento di rec che soddisfa lo schedule (l'effetto non Š determinato se lo schedule non Š ammissibile, quindi si assume che lo sia se c<>0). In pass viene calcolato il numero di passaggi relativi a quello schedule (se e' ammissibile) *) var t: byte; amm: boolean; begin t:=s.s; pass:=0; amm:=true; while (t<60) and (amm) do begin if (rec[t]=0) and (c=0) then amm:=false; inc(pass); rec[t]:=rec[t]+c; passaggi:=passaggi+c; t:=t+s.p end; ammissibile:=amm end; procedure ammissibili; (* Calcola tutti gli schedule ammissibili rispetto a rec e li mette nell'array sch *) var s: schedule; pass: byte; begin nsch:=0; for s.s:=0 to 29 do for s.p:=s.s+1 to 59-s.s do if (ammissibile(s,0,pass)) then begin inc(nsch); sch[nsch]:=s; sch[nsch].pass:=pass end end; procedure ordinaammissibili; (* L'array sch viene ordinato in ordine descrescente di pass. Ordinamento per selezione *) var i,j,maxi: word; t: schedule; begin for i:=1 to nsch-1 do begin maxi:=i; for j:=i+1 to nsch do if (sch[j].pass>sch[maxi].pass) then maxi:=j; t:=sch[maxi]; sch[maxi]:=sch[i]; sch[i]:=t end end; (* Una soluzione Š una sequenza di al pi— 17 schedule, in cui la prima sia ammissibile rispetto a rec, la seconda ammissibile rispetto a rec dopo la prima ecc. *) type soluzione=record nbus: byte; bus: array [1..17] of word end; var ottimo: soluzione; procedure outsol(var f: text; sol: soluzione); (* Output sul file f della soluzione sol *) var i: byte; begin for i:=1 to sol.nbus do writeln(f,sch[sol.bus[i]].s,' ',sch[sol.bus[i]].p); end; procedure cercaottimo(sol: soluzione); (* Quando la procedura viene invocata, sol Š una soluzione parziale, e rec Š aggiornato in base agli schedule di sol. Se sol Š una soluzione non definitiva, prova a prolungarla *) var start,i: word; unused: byte; begin if (passaggi=0) then (* Si tratta di una soluzione completa *) begin if (sol.nbus