Домашнее задание для учащихся, успешно программирующих на языке программирования Turbo Pascal program Vodoley_Problem; {задача о Водолее } uses Crt; const A_max = 7; { емкости сосудов } B_max = 5; Result = 1; { требуется получить } function Vodoley (A_max, B_max : Word; MessageOn : Boolean) : Word; {параметры функции - вместимость сосудов и флаг отключения сообщений; функция расчитывает число переливаний} var A,B,Num: Word;{текущее содержимое сосудов и количество переливаний } function Max (X, Y:Integer):Integer;{находит максимум двух чисел внутренняя для Vodoley} Begin if X>Y then Max:=X else Max:= Y; End; {Max} function NOD (A, B : Integer):Integer; { находит НОД; внутренняя для Vodoley} Begin while (A<>0) and (B<>0) do if A>B then A:=A mod B else B:=B mod A; NOD:= A+B; End; {NOD} procedure Message (S:String);{ печать сообщения; внутренняя для Vodoley} Begin if MessageOn then Writeln (S,A:3,B:3); Inc (Num); End; {Message} procedure Do_kraev_A; {набираем полный A с помощью B; внутренняя для Vodoley} Begin while (AResult) do begin if (B=0) then begin B:= B_max; Message ('Налить B '); end; A:= A+B; if (A>=A_max) then begin B:= A-A_max; A:= A_max; end else B:= 0; Message ('Перелить из B в A '); end; End; {Do_kraev_A} Begin {Vodoley} A:= 0; B:= 0; Num:= 0; if (Result>A_max) and (Result>B_max) or (Result mod NOD(A_max, B_max)<>0) then begin Message ('Невозможно '); Vodoley:=0; Exit; end else if Result=B_max then begin B:= B_max; Message ('Налить В '); end else begin Do_kraev_A; while (A<>Result) and (B<>Result) do begin A:= 0; Message ('Вылить из A '); if A_max>B_max then begin A:= B; B:= 0; Message ('Перелить из B в A '); end; Do_kraev_A; end; end; Vodoley:= Num; End; { Vodoley } BEGIN ClrScr; if Vodoley(A_max, B_max, False)= 0 m = p*A + q*B; n = r*A + s*B } while (m<>0) and (n<>0) do begin if (m >= n) then begin m:= m-n; p:= p-r; q:= q-s;end else begin n:= n-m; r:= r-p; s:= s-q; end; end; if (m=0) then Writeln (Res div n*r:3, Res div n*s:3) else Writeln (Res div m*p:3, Res div m*q:3); END. Эта же идея "работает" и в случае, когда сосудов не два, а больше. Например, ключ к получению в бочке 1 литра с помощью сосудов емкостями по 17, 32 и 45 литров лежит в представлении 1=17?(-44)+32?22+45. Множитель, стоящий при каждом числе соответствует количеству переливов данным сосудом (положительное значение – в бочку, отрицательное – из бочки).