Тема 3: Аналитическая геометрия

«Газон»

Фермер Иван с юности следит за своим газоном. Газон можно считать плоскостью, на которой в каждой точке с целыми координатами растет один пучок травы.

В одно из воскресений Иван воспользовался газонокосилкой и постриг некоторый прямоугольный участок газона. Стороны этого участка параллельны осям координат, а две противоположные вершины расположены в точках (x1, y1) и (x2, y2). Следует отметить, что пучки травы, находящиеся на границе этого прямоугольника, также были пострижены.

Довольный результатом Иван купил и установил на газоне дождевальную установку. Она была размещена в точке с координатами (x3, y3) и имела радиус действия струи r. Таким образом, установка начала поливать все пучки, расстояние от которых до точки (x3, y3) не превышало r.

Все было хорошо, но Ивана заинтересовал следующий вопрос: сколько пучков травы оказалось и пострижено, и полито в это воскресенье?

Требуется написать программу, которая позволит дать ответ на вопрос Ивана.

Входные данные: lawn.in. В первой строке входного файла содержатся четыре целых числа 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.out. В выходной файл необходимо вывести одно целое число — число пучков травы, которые были и пострижены, и политы.

Пример входных и выходных данных

lawn.in lawn.out
0 0 5 4 4 0 3

{Одно из возможных решений данной задачи заключается в следующем. Для каждой прямой, содержащей все пучки травы с равной координатой по оси абсцисс (аналогично можно рассматривать и ось ординат), найдем ее точки пересечения с окружностью, отображающей область действия поливальной установки, если, конечно, такие точки существуют. Получив данные точки, не сложно посчитать количество пучков травы на данной прямой одновременно и политых, и постриженных. Далее, просуммировав найденные числа для всех прямых, можно найти ответ на поставленную задачу.}

Var

x1,y1,x2,y2,x3,y3,x: longint;

k,r,y : longint;

input,output: text;

{функция определяет количество пучков травы, которые политы и подстрижены в исследуемом ряду}

functionkol(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 {количество политых и подстриженных пучков равно 0}

else{иначе}

Begin

{определяем минимальную координату Y пучка травы, который полит}

min:=y1;

ifz1>y1 then

min:=z1;

{определяем максимальную координату Y пучка травы, который полит}

max:=y2;

ifz2<y2 then

max:=z2;

k:=max-min+1 {считаем количество политых пучков травы в, принадлежащих подстриженной области}

end;

kol:=k

end;

Begin

{связываем файловые переменные и файлы, открываем для чтения и записи}

assign(input, 'lawn.in');

reset(input);

assign(output, 'lawn.out');

rewrite(output);

{считываем координаты вершин прямоугольной области}

readln(input,x1,y1,x2,y2);

{считываем координаты центра области полива и радиус полива}

read(input,x3,y3,r);

k:=kol(x3,y3-r,y3+r); {определяем, количество подстриженных и политых пучков травы в вертикальном ряду, проходящем через центр площади полива}

y:=r;

forx:=1 tor-1 do{пересчет всех вертикальных рядов, которые вмещаются на территорию от края до центра площади полива (не включая центральный ряд)}

Begin

whilesqr(x)+sqr(y)>sqr(r) do{определяется граничная точка y, принадлежащая площади полива}

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.

Тема 4: Перебор вариантов

«Буратино в замке»

В старинный замок имеет форму квадрата N×N комнат. В каждой комнате расставлены сундуки с золотыми монетами. Буратино находится в левой верхней комнате и мечтает, собрав как можно больше монет добраться до правой нижней комнаты. С каждой комнаты он может перейти с соседнюю справа или снизу. Буратино так же хочет запомнить маршрут, который он пройдет. Помогите Буратино.

Входные данные: Input.txt. В первой строке файла находится одно число N (1≤N≤30). В каждой i-ой из следующих N строк находится N чисел, которые обозначают количество монет в комнате (i,j).

Выходные данные: Output.txt. в первую строку файла выводится одно целое число – количество монет, которые удалось собрать Буратино. Во второй строке – маршрут – номера комнат, в которых побывал Буратино, начиная с комнаты (N,N) и заканчивая комнатой (1,1).



Input.txt Output.txt
7 1 4 9 3 3 8 4 2 1 8 1 6 7 7 2 7 4 4 5 4 5 2 6 5 (1,1) (2,1) (2,2) (2,3) (3,3) (3,4) (3,5) (4,5) (5,5)

Const

File_Dat='Input.txt';{константа хранит имя входного файла}

File_Sol='Output.txt';{константа хранит имя выходного файла}

Var

X:array[1..30,1..30] ofLongint;{массив для хранения количества монет в комнатах}

Y:array[0..30,0..30] oflongint;{массив для хранения сумм монет при переходе}

n,i,j: byte;

Begin

assign(Input, File_Dat);{связываем файловую переменную и входной файл}

reset(Input);{открываем файл для чтения}

readln(N);{считываем количество комнат на этаже}

{считываем количество монет в каждой комнате и заполняем массив}

fori:=1 toN do

forj:=1 toN do

read(X[i,j]);

close(Input);{закрываем входной файл}

{заполняем массив сумм нулями}

fori:=0 ton do

forj:=0 ton do

Y[i,j]:=0;

{Заполняем массив сумм}

fori:=1 toN do

forj:=1 toN do

ifY[i-1,j]>Y[i,j-1] then{Определяем комнату с наибольшим количеством монет}

Y[i,j]:=X[i,j]+Y[i-1,j]{записываем в массив сумм сумму монет текущей и соседней комнаты снизу}

Else

Y[i,j]:=X[i,j]+Y[i,j-1];{записываем в массив сумм сумму монет текущей и соседней комнаты справа}

assign(Output,File_Sol);{связываем выходной файл и файловую переменную}

rewrite(Output);{открываем файл для записи}

writeln(Y[n,n]);{выводим максимальное количество монет}

write('(',n,',',n,')'); {вывод координат последней комнаты}

{вывод пути, обратный обход массива сумм}

i:=n;

j:=n;

s:='';

{Обход массива сумм в обратную сторону}

while(i>0) and(j>0) do

Begin

if(Y[i,j]-X[i,j])=Y[i-1,j] theni:=i-1

elsej:=j-1;

if(i<>0) and(j<>0) then

write(Output,'(',i,',',j,')');

end;

close(Output);

end.


Наши рекомендации