Газон
Региональный этап Всероссийской
олимпиады школьников по информатике 2008/2009 учебного года
Первый тур
[к
списку задач]
Задача 2. Газон
Имя входного файла: |
lawn.in |
Имя выходного файла: |
lawn.out |
Максимальное время работы на
одном тесте: |
2 секунды |
Максимальный объем используемой
памяти: |
64 мегабайта |
Фермер Иван с юности следит за своим газоном. Газон можно
считать плоскостью, на которой в каждой точке с целыми
координатами растет один пучок травы.
В одно из воскресений Иван воспользовался газонокосилкой и
постриг некоторый прямоугольный участок газона. Стороны этого
участка параллельны осям координат, а две противоположные
вершины расположены в точках (x1, y1) и (x2, y2). Следует
отметить, что пучки травы, находящиеся на границе этого
прямоугольника, также были пострижены.
Довольный результатом Иван купил и установил на газоне
дождевальную установку. Она была размещена в точке с
координатами (x3, y3) и имела радиус действия струи r. Таким
образом, установка начала поливать все пучки, расстояние от
которых до точки (x3, y3) не превышало r.
Все было хорошо, но Ивана заинтересовал следующий вопрос:
сколько пучков травы оказалось и пострижено, и полито в это
воскресенье?
Требуется написать программу, которая
позволит дать ответ на вопрос Ивана.
Формат входных данных
В первой строке входного файла содержатся четыре целых числа
x1, y1, x2, y2 (−100 000 ≤ x1 < x2 ≤ 100 000; −100 000 ≤ y1 < y2
≤ 100 000).
Во второй строке входного файла содержатся три целых числа
x3, y3, r (−100 000 ≤ x3, y3 ≤ 100 000; 1 ≤ r ≤ 100 000)
Формат выходных данных
В выходной файл необходимо вывести одно целое число — число
пучков травы, которые были и пострижены, и политы.
Пример входных и выходных данных
lawn.in |
lawn.out |
0 0 5 4
4 0 3
|
14
|
Иллюстрация к примеру
Краткие методические рекомендации по решению задачи
Одно из возможных решений данной задачи заключается в
следующем. Для каждой прямой, содержащей все пучки травы с
равной координатой по оси абсцисс (аналогично можно
рассматривать и ось ординат), найдем ее точки пересечения с
окружностью, отображающей область действия поливальной
установки, если, конечно, такие точки существуют. Получив данные
точки, не сложно за время O(1) посчитать количество пучков травы
на данной прямой одновременно и политых, и постриженных. Это
делается с помощью операции вычисления целой части числа. Далее,
просуммировав найденные числа для всех прямых, можно найти ответ
на поставленную задачу.
Не сложно показать, что время работы рассматриваемого решения
будет O(r).
Возможные ошибки
Можно применить "лобовое" решение, т.е.
создать два или три массива, но на самом деле нужен только
один размером 100 элементов. При лобовом решении необходим
массив в 100000 элементов, а создать его в
Turbo Pascal
не удастся. Самое интересное, что
лобовое решение проходит если использовать компилятор
Free Pascal.
Текст программы на Паскале:
type
abc=Int64;
var
x1,y1,x2,y2,x3,y3,x: longint;
k,r,y : abc;
input,output: text;
function kol(x,z1,z2:longint):longint;
var
min,max,k: longint;
begin
if (x<x1)or(x>x2)or(z1>y2)or(z2<y1) then
k:=0
else
begin
min:=y1;
if z1>y1 then
min:=z1;
max:=y2;
if z2<y2 then
max:=z2;
k:=max-min+1
end;
kol:=k
end;
begin
assign(input, 'input.txt');
reset(input);
assign(output, 'output.txt');
rewrite(output);
readln(input,x1,y1,x2,y2);
read(input,x3,y3,r);
k:=kol(x3,y3-r,y3+r);
y:=r;
for x:=1 to r-1 do
begin
while sqr(x)+sqr(y)>sqr(r) do
y:=y-1;
k:=k+kol(x3+x,y3-y,y3+y)+kol(x3-x,y3-y,y3+y)
end;
k:=k+kol(x3+r,y3,y3)+kol(x3-r,y3,y3);
write(output,k);
close(input);
close(output);
end.
[к
списку задач]
|