Головна
Оргкомітет та журі
Реєстрація
Таблиця учасників
Тренувальний тур
Розв'язок тренувального туру
Перший тур
Другий тур
Розв'язок 3 туру


Програмний код розв'язку третього туру з перелiком тестів

Рішення задачі «Цілочисельні точки»

Для рішення цієї задачі потрібно використати формулу Піка, яка виглядає таким чином:

x = s - n div 2 + 1, де s – площа багатокутника, n – кількість цілочисельних точок на його сторонах.

Тобто, нам необхідно знати площу багатокутника. Нам відома формула S = 1/2 * |Σi=1n[OPi, OPi+1]|, або перетворення її і рахуючи координати точки O за (0; 0), отримуєм S = 1/2 * |(x1y2 - x2y1) + (x2y3 - x3y2) + ... + (xny1 - x1yn)|. Користуючись даною формулою і послідовно зчитуючи координати (потрібно не забувати про остатнього члена даної суми – зберегти координати першої точки), легко отримати площу – спочатку знайти суму всіх членів послідовності, пізніше взяти модуль і поділити на 2 (незабувши, що результат дійсне число).

На цьому ж кроці потрібно підрахувати кількість точок із цілочисельними координатами на сторонах багатокутника. Для цього потрібно підрахувати довжину проекцій кожної сторони на координатні осі. Кількість точок на стороні  - НСД довжин проекцій кожної сторони на координатні осі. НСД обчислюється за алгоритмом Евкліда. На кожному кроці заміняють більше з двох чисел на стачу від ділення (різницю від віднімання) більшого числа на менше, до цих пір поки одне із чисел не стане рівний нулю. Число, яке залишилось не рівне нулю буде найбільшим спільним дільником. При підрахунку точок слідує не забувати порахувати відрізок, який з’єднує остатню і першу точки багатокутника.

Тепер ми підрахували всі необхідні компоненти і осталось використати формулу Піка:  

x = s - n div 2 + 1.

 

program zadach_3;

  var

     a:array[1..1000,1..2] of longint;

     f,t:text;

     i,n:integer;

     s,dx,dy,ns,k:longint;

  procedure nsd (x,y:longint; var s:longint);

             begin

                if x=0 then s:=y

                           else

                               if y=0 then s:=x

                                          else

                                             begin

                                               while x<>y do

                                                   if x>y then x:=x-y

                                                              else y:=y-x;

                                                s:=x;

                                              end;

                end;

 begin

   assign(f,'input08.txt');

   reset (f);

   Readln(f,n);

   k:=0;

   readln(f,a[1,1],a[1,2]);

   for i:=2 to n do

     begin

       readln(f,a[i,1],a[i,2]);

       s:=s+(a[i-1,1]*a[i,2]-a[i,1]*a[i-1,2]);

       dx:=abs(a[i,1]-a[i-1,1]);

       dy:=abs(a[i,2]-a[i-1,2]);

        nsd(dx,dy,ns);

       k:=k+ns;

     end;

  close(f);

  s:=s+(a[n,1]*a[1,2]-a[1,1]*a[n,2]);

   dx:=abs(a[1,1]-a[n,1]);

   dy:=abs(a[1,2]-a[n,2]);

   nsd(dx,dy,ns);

   k:=k+ns;

   s:=round(abs(s)/2);

   s:=s-k div 2 +1;

   assign(t,'e.out');

   rewrite(t);

   writeln(t,s);

   close(t);

   end.

 

Перших п’ять тестів оцінюються по 10 балів.

6,7 – 15 балів.(вихід за тип Longint);

8 – 20 балів (1000 точок).

ТЕСТ 1
ВІДПОВІДЬ 1
ТЕСТ 2
ВІДПОВІДЬ 2
ТЕСТ 3
ВІДПОВІДЬ 3
ТЕСТ 4
ВІДПОВІДЬ 4
ТЕСТ 5
ВІДПОВІДЬ 5
ТЕСТ 6
ВІДПОВІДЬ 6
ТЕСТ 7
ВІДПОВІДЬ 7
ТЕСТ 8
ВІДПОВІДЬ 8