var
m,h:integer;
am,ah:integer;
c:integer;
begin
{вводим часы}
repeat
write('Enter h:');{выводим сообщение}
readln(h);{вводим часы}
until (h>=0)and(h<12);{проверяем правильность ввода}
{вводим минуты}
repeat
write('Enter m:');{выводим сообщение}
readln(m);{вводим минуты}
until (m>=0)and(m<60);{проверяем правильность ввода}
c:=0;{сбрасываем счетчик}
repeat
am:=m*6;{считаем угол минутной стрелки}
ah:=h*30+round(int(m*30/60));{считаем угол часовой стрелки}
h:=(h + ((m+1) div 60))mod 12;{увеличиваем часы}
m:=(m + 1)mod 60;{увеличиваем минуты}
inc(c);{увеличиваем счетчик}
until abs(am-ah)<4;{пока не будет совпадения}
write('Result :',c:5,h:5,':',m:2);{выводим результат}
Readln;
end.
Прежде всего, необходимо отметить, что в задаче принят интервал от полуночи до полудня, то есть от 0 часов 0 минут до 11 часов 59 минут.
За один оборот (60 делений) минутной стрелки часовая стрелка перемещается на 1 часовое деление, то есть на 5 минутных делений.
Таким образом, за число минут m, прошедшее от 0, часовая стрелка переместится на m/12 делений.
С другой стороны, рассмотрим, на сколько делений от нулевого будет смещена минутная стрелка. При этом считаем, что перемещение, например, на 65 делений приведет к тому, что минутная стрелка будет смещена на 65-60=5 делений от нуля.
Задача заключается в том, чтобы найти все такие возможные положения, где часовая и минутная стрелки совпадают. Для этого достаточно решить уравнение
m/12=m-h*60 (1),
где h =0,1,2,..11 – число полных часов, считая от полуночи.
После преобразования получаем 11*m/12=h*60,
m=720*h/11 (2).
Как мы видим, уравнение (2) имеет только одно целочисленное решение, при h=0 (или h=11), что, по сути, означает то же самое, так как при h=11, m=720, то есть полдень.
Уточним постановку задачи. Будем искать любое ближнее (не обязательно на минутном делении) совпадение часовой и минутной стрелок.
Для этого разделим задачу на части.
1.По заданному времени в часах и минутах вычисляем количество минут от полуночи по формуле
mполн=m+h*60 (3)
2.Находим целое число часов совпадения, следующее за текущим временем по формуле
hсовп=[ mполн *11/720]+ (4)
Здесь []+ означает округление с избытком.
3.Находим число минут от полуночи до пересечения стрелок при найденном числе часов
mсовп=[720*hсовп/11]- (5)
Здесь []- означает округление с недостатком.
4.Вычисляем разность
dm = mсовп -m (6).
Примеры расчета.
Пример I.
Заданное время. 01.05
1.m=1*60+5=65
2.h’=[65*11/720]+=[0.99]+=1
3.m’=[720*1/11]-=[65.4]-=65
4.dm=65-65=0
Пример II.
Заданное время. 01.06
1.m=1*60+5=66
2.h’=[66*11/720]+=[1.008]+=2
3.m’=[720*2/11]-=[130.9]-=130
4.dm=130-66=64
Пример III.
Заданное время. 00.00
1.m=0*60+0=0
2.h’=[0*11/720]+=[0]+=0
3.m’=[720*0/11]-=[0]-=0
4.dm=0-0=0
Пример IV.
Заданное время. 11.59
1.m=11*60+59=719
2.h’=[719*11/720]+=[10.98]+=11
3.m’=[720*11/11]-=[720]-=720
4.dm=720-719=719
program Strelki;
(*
mполн=m+h*60
hсовп=[mполн*11/720]+
mсовп=[720*hсовп/11]-
dm = mсовп-mполн
*)
type
TErrLevel = 0..3;
{ тип ошибки
0 - нет ошибки,
1 - неверные часы,
2 - неверные минуты,
3 - неверные часы и минуты }
var
h : integer; { данное число часов }
m : integer; { данное число минут }
InputError: TErrLevel; { уровень ошибки }
function ceil(a: real): integer;
{ возвращает целое, не меньшее заданного вещественного }
{ применимо: a>=0, a<MaxInt }
var
inta : integer;
begin
inta := trunc(a); { отбрасываем дробную часть }
if inta<a then { если дробная часть была }
ceil:= inta+1
else
ceil:= inta;
end; { ceil }
function MinDoSovp(h,m: integer): integer;
{ минут от заданного времени до совпадения }
var
k : real; { коэффициент перевода, k=720/11 }
mpoln: integer; { число минут от полуночи до заданного времени }
hsovp: integer; { число часов от полуночи до ближайшего следующего совпадения }
msovp: integer; { число минут от полуночи до ближайшего следующего совпадения стрелок }
begin
k:= 720/11;
mpoln := m+h*60;
hsovp := ceil(mpoln/k);
msovp := trunc(hsovp*k);
MinDoSovp := msovp-mpoln;
end; { MinDoSovp }
procedure vvod(var h,m: integer; var ErrLevel: TErrLevel);
{ ввод часов и минут, запись уровня ошибки }
begin
write('h=');
readln(h);
write('m=');
readln(m);
ErrLevel := 0;
if not (h in [0..11]) then
ErrLevel := ErrLevel+1;
if not (m in [0..59]) then
ErrLevel := ErrLevel+2;
end; { vvod }
procedure ErrMsg(ErrLevel: TErrLevel);
{ печать сообщения об ошибке }
const
Msg1 = 'Неверный ввод часов';
Msg2 = 'Неверный ввод минут';
Msg99 = 'Неопознанная ошибка';
begin
case ErrLevel of
0:;
1: writeln(Msg1);
2: writeln(Msg2);
3:
begin
writeln(Msg1);
writeln(Msg2);
end;
else
writeln(Msg99);
end;
end; { ErrMsg }
begin { основной блок }
vvod(h,m, InputError);
if InputError>0 then { если ошибка ввода }
ErrMsg(InputError)
else
writeln('С заданного времени до совпадения стрелок пройдет ', MinDoSovp(h,m), ' мин.');
readln;
end.
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.