Условная компиляция
{$ define <Имя режима>} Включает режим компиляции с именем <Имя режима>.
{$ ifdef <Имя режима>} < Операторы, которые «видны» компилятору только в режиме “<Имя режима>”> {$ else} < Операторы, которые «видны» компилятору только в противоположном режиме > {$ endif } Классическая развилка на этапе компиляции.
{$ ifdef <Имя режима>} < Операторы, которые «видны» компилятору только в режиме “<Имя режима>”> {$ endif } Упрощенная развилка.
{$ ifndef <Имя режима>} Заголовок «перевернутой» развилки Ниже приводится текст программы, которая строит «самый дешевый путь» из левого верхнего угла матрицы размерами в правый нижний угол любым из двух ранее описанных методов. Первый метод (рекурсивный) включается, если «НЕ закомментирована» строка {$define RECOURSIVE}.
Второй метод (динамического программирования) включается, если эта строка «закомментирована», т.е. имеет вид // {$define RECOURSIVE}.
program Project3;
{$APPTYPE CONSOLE}
Uses SysUtils;
//{$define RECOURSIVE}
Const mMax = 20; nMax = 20;
Type MyRecord = record
{$ ifdef RECOURSIVE} CellPrice, Frequency: integer; {$ else } CellPrice, PathPrice: integer; {$ endif }
Direction: char; end;
MyArray = array [1.. mMax, 1.. nMax] of MyRecord;
Var m, n, p: integer; A: MyArray; tStart, tFinish: TDateTime;
procedure InputArray(var C: MyArray); Var F: Text; i, j: Integer; Begin Assign(F, 'c:\a.txt'); Reset(F);
Readln(F, m); if (m < 1) or (m > mMax) then Halt;
Readln(F, n); if (n < 1) or (n > nMax) then Halt; for i:= 1 to m do Begin for j:= 1 to n do Begin Read(F, C[i][j].CellPrice);
{$ ifdef RECOURSIVE} C[i][j].Frequency:= 0; {$ else } C[i][j].PathPrice:= 0; {$ endif }
C[i][j].Direction:= '?'; end; Readln(F); end; Close(F); end; procedure ShowPrices(var C: MyArray); Var i, j: Integer; Begin Writeln('ShowPrices');
for i:= 1 to m do Begin for j:= 1 to n do Write(C[i][j].CellPrice: 5);
Writeln; end; end;
{$ ifdef RECOURSIVE} procedure ShowFrequencies(var C: MyArray); Var i, j: Integer; Begin Writeln('ShowFrequencies');
for i:= 1 to m do Begin for j:= 1 to n do Write(C[i][j].Frequency: 5);
Writeln; end; end; {$ endif }
procedure ShowDirections(var C: MyArray); Var i, j: integer; Begin Writeln('ShowDirections');
for i:= 1 to m do Begin for j:= 1 to n do Write(C[i][j].Direction: 3);
Writeln; end; end;
function Right(i, j: integer): boolean; Begin if j < n then Right:= true else Right:= false; end;
function Down(i, j: integer): boolean; Begin if i < m then Down:= true else Down:= false; end;
{$ ifdef RECOURSIVE}
function BestPathRecoursive(i, j: integer; var C: MyArray): integer; Var id, ir: integer; Begin Inc(C[i][j].Frequency);
if (i = m) and (j = n) then BestPathRecoursive:= 0 Else Begin IfRight(i, j) then ir:= C[i][j + 1].CellPrice + BestPathRecoursive(i, j + 1, C) Else ir:= -1;
IfDown(i, j) then id:= C[i + 1][j].CellPrice + BestPathRecoursive(i + 1, j, C) Else id:= -1;
if (ir >= 0) and (id >= 0) then Begin Ifir < id then Begin C[i][j].Direction:= 'r'; BestPathRecoursive:= ir; End Else Begin C[i][j].Direction:= 'd'; BestPathRecoursive:= id; end; End Else if ir >=0 then Begin C[i][j].Direction:= 'r'; BestPathRecoursive:= ir; End Else if id >= 0 then Begin C[i][j].Direction:= 'd'; BestPathRecoursive:= id; End Else Halt; end; end;
{$ else } // NonRecoursive
procedure BestPathNonRecoursive(var C: MyArray); Var i, j, k, ir, id: integer;
Begin C[m][n].PathPrice:= 0;
for k:= m + n - 1 downto 1 do for i:= m downto 1 do Begin j:= k - i; if j > n then break; if j < 1 then continue;
|