program Mak3; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, message, maklib { you can add units after this }; Type TRec=Record Start,Finish:Longint; Sum:Int64; Used:Boolean; End; Var Id,MaxId:Longint; Curent, First, Last, Max:TRec; Function InitRec:TRec; // Ustaw Pola; Begin Result.Start :=0; Result.Finish:=0; Result.Sum :=0; Result.Used :=False; End; Function SetRec(Const ARec:TRec):TRec;inline; Begin Result:=ARec; // Przepisz Record; Result.Used:=True; // Ustaw Flage Uzycia End; Function GetRec(AInst:Longint):TRec; Begin Result.Start :=GetInt(AInst); Result.Finish:=GetInt(AInst); Result.Sum :=GetLL (AInst); Result.Used :=Boolean(GetInt(AInst)); End; Procedure GetAllRec(AInst:Longint); Begin Receive(AInst); First:=GetRec(AInst); Max :=GetRec(AInst); Last :=GetRec(AInst); End; Procedure PutRec(Const ARec:TRec); Begin PutInt( 0, ARec.Start ); PutInt( 0, ARec.Finish ); PutLL ( 0, ARec.Sum ); PutInt( 0, Byte(ARec.Used)); End; Procedure FindMax; Var AStart, AFinish, Loop:LongInt; Begin Receive(0); // Obierz wiadomosc od Instancji "0" AStart :=GetInt(0); // Poczatek przeszukiwanego zakresu AFinish:=GetInt(0); // Koniec przeszukiwanego zakresu Curent:=InitRec; // Zeruj rekordy First :=InitRec; Last :=InitRec; Max :=InitRec; Curent.Start:=AStart; // Poczatkowa pozycja For Loop:=AStart to AFinish do Begin // Przeczytaj zakres dla danej Instancji Curent.Sum :=Curent.Sum+ElementAt(Loop);// Dodaj sume Curent.Finish:=Loop; // Przesun koniec zakresu If Curent.Sum>=Max.Sum Then Begin // Czy wieksza od Maksa Max :=SetRec(Curent); // Przepisz rekord End; If Curent.Sum<=0 Then Begin Curent.Sum:=0; If Not First.Used Then First:=SetRec(Max );//Ustaw pierwszy Maks Curent:=InitRec; Curent.Start:=Loop+1; End; End; Curent.Finish:=Loop; If Not First.Used Then First:=SetRec(Max); Last:=Curent; PutRec( First ); PutRec( Max ); PutRec( Last ); Send (0 ); End; Procedure PrintMax; var Loop:Longint; TotalMax:Int64; Prev:TRec; Begin GetAllRec(1); TotalMax:=Max.Sum; Prev:=Last; For Loop:=2 to MaxId-1 do Begin GetAllRec(Loop); Prev.Sum:=Prev.Sum+First.Sum; If Prev.Sum>TotalMax Then TotalMax:=Prev.Sum; If Max .Sum>TotalMax Then TotalMax:=Max .Sum; If Last.Sum>TotalMax Then TotalMax:=Last.Sum; Prev:=Last; End; WriteLn(TotalMax); End; Var Loop, Interval:LongInt; Test:Boolean; Begin MaxId:=NumberOfNodes; Interval := Size Div MaxId; Test :=True; // Flaga If Interval<10 Then Begin // Czy oplaca sie wysylac do instancji Interval:=Size; // Ustaw zakres Test:=False; // Zmien MaxId:=0; End; If MyNodeId=0 Then Begin If Test And (MaxId>1)Then Begin For Loop:=0 to MaxId-2 do Begin PutInt( Loop, 1+Loop*Interval ); PutInt( Loop, Loop*Interval + Interval); Send ( Loop ); End; Loop:=Loop+1; PutInt( Loop, 1+Loop*Interval); PutInt( Loop, Size ); Send ( Loop ); End Else Begin PutInt( 1, 1 ); PutInt( 1, Size ); Send ( 1 ); End; // FindMax; PrintMax; End Else Begin FindMax; End; // ReadLn; End.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | program Mak3; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, message, maklib { you can add units after this }; Type TRec=Record Start,Finish:Longint; Sum:Int64; Used:Boolean; End; Var Id,MaxId:Longint; Curent, First, Last, Max:TRec; Function InitRec:TRec; // Ustaw Pola; Begin Result.Start :=0; Result.Finish:=0; Result.Sum :=0; Result.Used :=False; End; Function SetRec(Const ARec:TRec):TRec;inline; Begin Result:=ARec; // Przepisz Record; Result.Used:=True; // Ustaw Flage Uzycia End; Function GetRec(AInst:Longint):TRec; Begin Result.Start :=GetInt(AInst); Result.Finish:=GetInt(AInst); Result.Sum :=GetLL (AInst); Result.Used :=Boolean(GetInt(AInst)); End; Procedure GetAllRec(AInst:Longint); Begin Receive(AInst); First:=GetRec(AInst); Max :=GetRec(AInst); Last :=GetRec(AInst); End; Procedure PutRec(Const ARec:TRec); Begin PutInt( 0, ARec.Start ); PutInt( 0, ARec.Finish ); PutLL ( 0, ARec.Sum ); PutInt( 0, Byte(ARec.Used)); End; Procedure FindMax; Var AStart, AFinish, Loop:LongInt; Begin Receive(0); // Obierz wiadomosc od Instancji "0" AStart :=GetInt(0); // Poczatek przeszukiwanego zakresu AFinish:=GetInt(0); // Koniec przeszukiwanego zakresu Curent:=InitRec; // Zeruj rekordy First :=InitRec; Last :=InitRec; Max :=InitRec; Curent.Start:=AStart; // Poczatkowa pozycja For Loop:=AStart to AFinish do Begin // Przeczytaj zakres dla danej Instancji Curent.Sum :=Curent.Sum+ElementAt(Loop);// Dodaj sume Curent.Finish:=Loop; // Przesun koniec zakresu If Curent.Sum>=Max.Sum Then Begin // Czy wieksza od Maksa Max :=SetRec(Curent); // Przepisz rekord End; If Curent.Sum<=0 Then Begin Curent.Sum:=0; If Not First.Used Then First:=SetRec(Max );//Ustaw pierwszy Maks Curent:=InitRec; Curent.Start:=Loop+1; End; End; Curent.Finish:=Loop; If Not First.Used Then First:=SetRec(Max); Last:=Curent; PutRec( First ); PutRec( Max ); PutRec( Last ); Send (0 ); End; Procedure PrintMax; var Loop:Longint; TotalMax:Int64; Prev:TRec; Begin GetAllRec(1); TotalMax:=Max.Sum; Prev:=Last; For Loop:=2 to MaxId-1 do Begin GetAllRec(Loop); Prev.Sum:=Prev.Sum+First.Sum; If Prev.Sum>TotalMax Then TotalMax:=Prev.Sum; If Max .Sum>TotalMax Then TotalMax:=Max .Sum; If Last.Sum>TotalMax Then TotalMax:=Last.Sum; Prev:=Last; End; WriteLn(TotalMax); End; Var Loop, Interval:LongInt; Test:Boolean; Begin MaxId:=NumberOfNodes; Interval := Size Div MaxId; Test :=True; // Flaga If Interval<10 Then Begin // Czy oplaca sie wysylac do instancji Interval:=Size; // Ustaw zakres Test:=False; // Zmien MaxId:=0; End; If MyNodeId=0 Then Begin If Test And (MaxId>1)Then Begin For Loop:=0 to MaxId-2 do Begin PutInt( Loop, 1+Loop*Interval ); PutInt( Loop, Loop*Interval + Interval); Send ( Loop ); End; Loop:=Loop+1; PutInt( Loop, 1+Loop*Interval); PutInt( Loop, Size ); Send ( Loop ); End Else Begin PutInt( 1, 1 ); PutInt( 1, Size ); Send ( 1 ); End; // FindMax; PrintMax; End Else Begin FindMax; End; // ReadLn; End. |