Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Олимпиадные задачи с решениями на Turbo Pascal


Служба Рассылок Subscribe.Ru
Олимпиадные задачи c решениями на Turbo Pascal

Олимпиадные задачи с решениями на Turbo Pascal


Рассылка проекта Sapisoft.By.Ru [#011]


Подписчиков на 08.02.2002 - 2520


Главная Программы Задачи Рассылки Гостевая книга Контакты

Здравствуйте!


  В рамках проекта Sapisoft открывается новый проект - "Задача в неделю". Руководитель - Алексеев А.В. Форма для подписки на рассылку - в конце номера. Подробная информация - в разделах "Задачи" и "Рассылки" на нашем сайте.
  В этом выпуске позвольте представить вам ещё одну задачу, любезно предоставленную HellMan'ом [alexec@polarcom.ru].

Ограда (3 уровень)


Условие:
Рабочие хотят огородить площадку для проведения строительных работ. Для этого они должны использовать K секций забора. Длина каждой секции забора не превышает 1000 метров. Необходимо определить, какую максимальную площадь можно огородить имеющимися секциями.

Технические условия:
Первая строка входного файла input.txt содержит K (K <= 100). Вторая строка содержит K целых чисел - длины имеющихся секций забора. Выходной файл output.txt должен содержать одно число - максимальную площадь, которую можно огородить (с точностью 3 знака после запятой).

Примеры файлов:
Input.txt Output.txt
3
3 4 5
6.000

Решение: (by HellMan [alexec@polarcom.ru])

---------- cut ----------
Идея решения такая: максимальная площадь получится, если вписать многоугольник в окружность. Радиус находим двоичным поиском. Определяем, подходит радиус или нет, вычисляя сумму центральных углов и сравнивая с 2Pi.
Предусмотрен случай, когда центр окружности лежит вне многоугольника (переменная-переключатель altmode). Возможно, точность надо подстроить (все эти 1e-16), потому что эти значения (и их соотношения) очень важны для корректной работы.

---------- cut ----------

{$A-,B-,D+,E-,F-,G-,I-,L+,N+,O-,P-,Q-,R-,S-,T-,V-,X-,Y+}
{$M 16384,0,655360}

program Fence;

type
  returnValue = -1..1;

const
  pi2: extended = 6.2831853071795865;

var
  f: text;
  k, i: byte;
  a: array[1..100] of word;
  max, sum: longint;
  ml, mr, r, ar: extended;
  res: returnvalue;
  done: boolean;

label
  OUT;

function test(const r: extended; const altmode: boolean): returnvalue;
var ang, max, sum: extended;
    i: byte;
begin
  max := 0;
  sum := 0;
  for i := 1 to k do

  begin
    ang := sqrt(sqr(r) - 0.25 * sqr(a[i]));
    if abs(ang) <= 1e-25 then
    ang := 0.7853981633974483
      else
        ang := 2 * arctan(0.5 * a[i] / ang);
    sum := sum + ang;
    if max < ang then
    max := ang;
  end;
  if not altmode then

  begin
    if abs(sum - pi2) < 1e-7 then

    begin
      test := 0;
      exit;
    end;
  end;
  if altmode then

  begin
    sum := sum + pi2 - 2 * max;
    if abs(sum - pi2) < 1e-7 then

    begin
      test := 0;
      exit;
    end;
  end;
  if sum > pi2 then
  test := 1
    else
     test := -1;
end;

function area(const r: extended; const altmode: boolean): extended;
var i: byte;
    p, ar: extended;
begin
  ar := 0;
  for i := 1 to k do

  begin
    p := r + 0.5 * a[i];
    ar := ar + (p - r) * sqrt(p * (p - a[i]));
  end;
  if altmode then

  begin
    p := r + 0.5 * max;
    ar := ar - 2 * (p - r) * sqrt(p * (p - max));
  end;
  area := ar;
end;

begin
  assign(f, 'input.txt');
  reset(f);
  readln(f, k);
  max := 0;
  sum := 0;
  for i := 1 to k do

  begin
    read(f, a[i]);
    inc(sum, a[i]);
    if a[i] > max then
    max := a[i];
  end;
  close(f);
  if max >= sum / 2 then

   begin
    ar := 0;
    goto OUT;
  end;

  ml := max / 2;
  mr := sum / 2;
  done := false;

  while mr - ml > 1e-16 do

  begin
    r := (ml + mr) / 2;
    res := test(r, false);
    if res = 0 then

    begin
      done := true;
      ar := area(r, false);
      break;
    end;
    if res = -1 then
    mr := r
      else
        ml := r;
  end;

  ml := max / 2;
  mr := sum / 2;
  while not done do

  begin
    if mr - ml < 1e-7 then

    begin
      ml := mr;
      mr := ml * 4;
    end;
    r := (ml + mr) / 2;
    res := test(r, true);
    if res = 0 then

    begin
      done := true;
      ar := area(r, true);
      break;
    end
     else
     if res = 1 then
     mr := r
       else
        ml := r;
  end;

  OUT:
  assign(f, 'output.txt');
  rewrite(f);
  writeln(f, ar:5:3);
  close(f);
end.


Рассылки проекта Sapisoft:

Новости проекта Sapisoft [Шамис Алексей]
Информация о выходе новых версий программ и прочих обновлениях на сайте.


Уроки программирования на Turbo Pascal [Галин Павел]
Хотите стать Великим Программистом? Начните свой путь к вершине славы с изучения языка Turbo Pascal. Он как нельзя лучше подходит для начинающих программистов и в то же время используется для разработки сложных "профессиональных" программ.

Олимпиадные задачи с решениями на Turbo Pascal [Шамис Алексей]
В рассылке публикуются решения интересных олимпиадных задач различного уровня. Периодичность - 2-3 раза в неделю. Каждый выпуск содержит решение 2-3 задач с подробным анализом описанием алгоритма решения.

Задача в неделю. Олимпиадные задачи по информатике [Алексеев Александр]
Каждый понедельник в рассылке публикуется задача, которую необходимо решить и в следующий понедельник прислать программу на тестирование. Решения проверяются и в пятницу публикуется разбор и итоги тестирования. По итогам работы за каждый месяц наиболее активные участники награждаются ценными призами.



Всегда рады видеть Вас на нашем сайте. Жду ваших предложений и замечаний, Шамис Алексей

Copyright © 2001-2002 by Shamis Alex.




http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное