Решения

advertisement
Решения
Задача №1. (2 балла) Здоровые хлопоты
В лагерь собираются поехать N детей и M взрослых. Каждый автобус вмещает K человек.
Значит, максимальное количество автобусов, укомплектованных двумя взрослыми
а1=целое(М/2). Количество автобусов, в которое уместятся все дети а2=целое(N/(К2)+0.5). Следовательно, если а1<a2 – выехать нельзя, если а2a1, количество автобусов
а=целое((N+М)/К+0.5).
Приведем решение А. Лобаневой:
program avtob;
var m,n,k,a:real;
begin
write('vvedite kolichectvo detei');
read(n);
write('vvedite kolichectvo vzroslih');
read(m);
write('vvedite kolichectvo mest v avtobusah');
read(k);
if k>2 then
begin
a:=round(n/(k-2));
if m/2>=a then
begin
a:=round((m+n)/k);
writeln (a);
end
else writeln ('nol');
end
else writeln ('nol');
end.
Задача №2. (5 баллов) Считалка
Для определения порядка выхода из круга, заведем массив, элементы которого
первоначально равны номерам детей. Начинаем считать по кругу, причем отсчитываем
только ненулевые элементы. Элемент массива, на котором закончился счет, сначала
выводим (как номер вышедшего из круга), а затем - зануляем.
program schitalka;
var nd,nch,i,kd,kch,kv:integer;
d,v:array [1..100] of byte;
begin
write('nd, nch='); read(nd,nch);
kv:=nd;kd:=0;
for i:=1 to nd do d[i]:=i;
while kv>1 do
begin
for kch:=1 to nch do
begin
kd:=kd+1;
while d[kd]=0 do begin
kd:=kd+1;
if kd>nd then kd:=1;
end;
end;
write(d[kd]:3); d[kd]:=0; kv:=kv-1;
end;
kd:=1;while d[kd]=0 do;writeln(d[kd]:3,' *');
end.
Задача №3. (4 балла) Простые Числа Фибоначчи
Сначала необходимо вычислить нужное количество чисел Фибоначчи. Затем, путем
анализа остатка деления каждого числа Ф на все числа, меньшие Ф/2, определить простые
и сосчитать их. Единственная (но большая) проблема в том, что числа в
последовательности резко нарастают и длины простых целых типов не хватает.
Приведем решение И. Загвоздина (без традиционного использования массива)
program Project3;
var
N,K1,K2,i,X:Integer;
N_1,N_2:Integer;
function Prost(X:Integer):Boolean;
var i:Integer;
begin
Prost:=True;
if (X = 1) or (x = 2) then Exit;
for i := 2 to X - 1 do
if X mod i = 0 then
begin
Prost:=False;
Exit;
end;
end;
begin
Readln(N); K1:=2; K2:=0;
N_1:=1; N_2:=1;
write(N_1,' ',N_2,' ');
for i := 3 to 2*N do
begin
X:=N_1+N_2;
N_1:=N_2; N_2:=X;
write(X,' ');
end;
Writeln('');
N_1:=1; N_2:=1;
write(N_1,' ',N_2,' ');
for i := 3 to 2*N do
begin
X:=N_1+N_2;
N_1:=N_2; N_2:=X;
if Prost(x) then
begin
write(X,' ');
if i <= N then
K1:=K1+1
else
K2:=K2+1;
end;
end;
Writeln('');
Write(K1,' ',K2);
Readln;
end.
Задача №4. (2 балла) Бронзовый призер
В данной задаче легче всего произвести частичное упорядочение массива результатов
методом выбора: сначала найти минимальное значение и переместить его на место
первого элемента. Затем найти минимальный элемент в части массива со второго
элемента до конца и переместить его на 2-е место, а затем найти минимальное в 3-й раз.
Так как по условию одинаковых результатов нет, то это и будет искомой величиной.
Можно не перемещать минимальное, а просто изменить его (здесь легко подобрать
заведомо «большое» значение), но искать следующее минимальное во всем массиве.
Приведем решение К.Гордиенко:
program GORDIENKO4;
uses crt;
var
a: array[1..1000] of real;
i,n,k,j,z:integer;
s:real;
begin
clrscr;
write('vvedite chislo sportsmenov ');
read(N);
for i:=1 to N do
begin
write('resultat ',i,' =');
read(a[i]);
end;
s:=a[1];
k:=1;
for j:=1 to N do
begin
s:=a[1];
for i:=1 to N do
if a[i]<=s then
begin
s:=a[i];
z:=i;
end;
a[z]:=32000;
if j=3 then
writeln('Mesto ',j,' resultat ',s:2:2);
end;
readln;
readln;
end.
Задача №5. (5 балла) Боевая задача
Эта задача является одним из вариантов широко известной в вычислительной геометрии
задачи о принадлежности точки многоугольнику (см. http://habrahabr.ru/post/144571/;
Задача о принадлежности точки многоугольнику в http://ru.wikipedia.org ).
Существует несколько способов ее решения, в частности, метод луча, когда из точки в
произвольном направлении проводится луч и выясняется, сколько раз он пересекает
стороны многоугольника. Если число пересечений –четное, то точка –вне многоугольника
(см. последовательное и понятное изложение в http://habrahabr.ru/post/144571/;).
Приведем решение Ю. Кабанова (хотя введенные новые типы здесь не способствуют
легкому пониманию алгоритма, зато дают возможность компактно решить задачу).
program task05;
type TPoint=record
x,y:real;
end;
type TRect=record
p:array[1..4] of TPoint;
end;
var i,j,n,s:integer;
points:array[1..1000] of TPoint;
rects:array[1..1000] of TRect;
vec1,vec2,vecp:TPoint;
f:text;
function dot_product(a,b:TPoint):real;
begin
dot_product := a.x*b.x + a.y*b.y;
end;
begin
assign(f,'input05.txt');
reset(f);
readln(f,n);
for i := 1 to n do
begin
read(f,points[i].x, points[i].y);
for j := 1 to 4 do
read(f,rects[i].p[j].x, rects[i].p[j].y);
readln(f);
end;
close(f);
for i := 1 to n do
begin
vec1.x := rects[i].p[2].x - rects[i].p[1].x;
vec1.y := rects[i].p[2].y - rects[i].p[1].y;
vec2.x := rects[i].p[4].x - rects[i].p[1].x;
vec2.y := rects[i].p[4].y - rects[i].p[1].y;
if (dot_product(vec1,vec2) <> 0) then
begin
vec2.x := rects[i].p[3].x - rects[i].p[1].x;
vec2.y := rects[i].p[3].y - rects[i].p[1].y;
end;
vecp.x := points[i].x - rects[i].p[1].x;
vecp.y := points[i].y - rects[i].p[1].y;
if (dot_product(vecp,vec1)/(dot_product(vec1,vec1)) >=0) and
(dot_product(vecp,vec1)/(dot_product(vec1,vec1)) <=1) and
(dot_product(vecp,vec2)/(dot_product(vec2,vec2)) >=0) and
(dot_product(vecp,vec2)/(dot_product(vec2,vec2)) <=1) then s:=s+1;
end;
assign(f,'output05.txt');
rewrite(f);
writeln(100*s/n:1:1);
close(f);
end.
Download