Описание Рассмотрим математический маятник, прикрепленный к началу координат математической нитью. Начальное положение маятника (-r,0). Если маятник отпустить, то он начнет колебаться, описывая полуокружность. Теперь представим себе, что в плоскость вбито несколько математических гвоздиков. Движение маятника в этом случае будет более сложным, но, в конце концов, он также начнет совершать некоторые периодические колебания Для нашего идеального математического мира считаются выполненными следующие условия:
Решение { ----------------- Compiler directives ------------------- } {$A+,B-,E-,F-,G-,N+,O-,P-,Q-,T-,V+,X+} {$M 65520,0,655360} { ------------------ Debug mode on/off -------------------- } {$DEFINE __DEBUG__} {$IFDEF __DEBUG__} {$D+,I+,L+,R+,S+,Y+} {$ELSE} {$D-,I-,L-,R-,S-,Y-} {$ENDIF} { --------------- End Compiler directives ----------------- } program pendulum; type TNails = array [1..501] of record x, y : extended; end; var nails : TNails; n, reduced : integer; i : integer; length : extended; x, y : extended; way_gone : extended; cur_lenght : extended; cur_center_x, cur_center_y : extended; cycle_length : extended; ang, smallest : extended; cur_i : integer; function ArcSin (x : extended) : extended; begin ArcSin := ArcTan (x / sqrt (1 - x*x)); end; function Distance (x1, y1, x2, y2 : extended) : extended; begin Distance := sqrt (sqr (x1 - x2) + sqr (y1 - y2)); end; function Angle (x1, y1, x2, y2 : extended) : extended; begin if (y1 = y2) and (x1 > x2) then Angle := 0.0 else if (y1 = y2) and (x1 < x2) then Angle := pi else if (x1 = x2) and (y1 > y2) then Angle := pi / 2 else if (x1 = x2) and (y1 < y2) then Angle := 3 * pi / 2 else if (x1 > x2) and (y1 > y2) then Angle := ArcTan ((y1 - y2) / (x1 - x2)) else if (x2 > x1) and (y1 > y2) then Angle := pi / 2 + ArcTan ((x2 - x1) / (y1 - y2)) else if (x2 > x1) and (y2 > y1) then Angle := pi + ArcTan ((y2 - y1) / (x2 - x1)) else Angle := 3 * pi / 2 + ArcTan ((x1 - x2) / (y2 - y1)); end; procedure Model (gone, c_x, c_y, len, a : extended); begin if (abs (c_y) < len) then begin inc (n); smallest := pi + ArcSin (abs (c_y) / len) - a; nails [n].x := c_x + sqrt (sqr (len) - sqr(c_y)); nails [n].y := 0; cur_i := n; end else smallest := 2*pi; i := 0; while (i < n) do begin inc (i); if ((nails [i].x = c_x) and (nails [i].y = c_y)) or (Distance (c_x, c_y, nails [i].x, nails [i].y) > len) then Continue; ang := Angle (c_x, c_y, nails [i].x, nails [i].y); ang := ang - a; if ang < 0 then ang := ang + 2*pi; if ang < smallest then begin smallest := ang; cur_i := i; end; end; if n = reduced + 1 then dec (n); if (smallest = 2*pi) then begin cycle_length := 2 * pi * len; end else if cur_i = n + 1 then begin cycle_length := 2 * (gone + smallest*len); end else begin Model (gone + smallest*len, nails [cur_i].x, nails [cur_i].y, len - Distance (c_x, c_y, nails [cur_i].x, nails [cur_i].y), a + smallest); end; end; begin assign (input, 'pendulum.in'); reset (input); read (n); read (length); reduced := 0; for i := 1 to n do begin read (x); read (y); if (y < 0) and (sqr (x) + sqr (y) <= sqr (length)) then begin inc (reduced); nails [reduced].x := x; nails [reduced].y := y; end; end; close (input); n := reduced; if (n = 0) then begin assign (output, 'pendulum.out'); rewrite (output); writeln ((2 * pi * length) : 1 : 2); close (output); Halt (0); end; cycle_length := 0; Model (0.0, 0.0, 0.0, length, 0.0); assign (output, 'pendulum.out'); rewrite (output); Writeln (cycle_length : 1 : 2); close (output); end. |
© Особенности национальных задач по информатике |