Главная страница

олимпиадная задача pascalabc. Задача 17 Детский праздник. Задача 17 Детский праздник


Скачать 92.55 Kb.
НазваниеЗадача 17 Детский праздник
Анкоролимпиадная задача pascalabc
Дата21.11.2022
Размер92.55 Kb.
Формат файлаdocx
Имя файлаЗадача 17 Детский праздник.docx
ТипЗадача
#804576

Задача 17 Детский праздник

Имя входного файла: INPUT.TXT

Имя выходного файла: OUTPUT.TXT

Максимальное время работы на каждом тесте: 10 секунд

Организаторы детского праздника планируют надуть для него M воздушных шариков. С этой целью они пригласили N добровольных помощников, i-й среди которых надувает шарик за Ti минут, однако каждый раз после надувания Zi шариков устает и отдыхает Yi минут. Теперь организаторы праздника хотят узнать, через какое время будут надуты все шарики при наиболее оптимальной работе помощников, и сколько шариков надует каждый из них. (Если помощник надул шарик, и должен отдохнуть, но больше шариков ему надувать не придется, то считается, что он закончил работу сразу после окончания надувания последнего шарика, а не после отдыха).

Формат входных данных

В первой строке входного файла находятся числа M и N (0≤M≤1000, 1≤N≤20). Следующие N строк содержат по три целых числа — Ti, Zi и Yi соответственно (1≤Ti,Yi≤100, 1≤Zi ≤1000)

Формат выходных данных

Выведите в выходной файл на первой строке число T – время, за которое будут надуты все шарики. На второй строке выведите N чисел – сколько шариков, надует каждый из приглашенных помощников. Разделяйте числа пробелами. Если распределений шариков несколько, выведите любое из них.

Примеры

INPUT.TXT

OUTPUT.TXT

10 3

1 2 3

3 10 3

2 4 3

8

4 2 4

1 3

1 1 100

2 1 100

3 1 100

1

1 0 0


Алгоритм решения

Для решения задачи применим жадный алгоритм.

Жадный алгоритм – это алгоритм, который на каждом шагу делает локально наилучший выбор в надежде, что итоговое решение будет оптимальным.

Будем по очереди добавлять шарики и отдавать для надувания следующий шарик тому помощнику, который надует шарик раньше всех. Эта схема приведет к оптимальному решению, так как мы выбираем каждый раз помощника с минимальным временем надувания.

Алгоритм решения задачи выглядит примерно так:

Заполняем данные по времени надувания, количеству шариков, надуваемых без перерыва и времени на отдых для каждого помощника.

Задаем начальное время

Рассчитываем время для каждого помощника на текущем шарике и запоминаем самое маленькое и помощника, увеличиваем количество шариков у выбранного помощника, проверяем – не пора ли отдыхать этому помощнику – если настало время отдыха, то увеличиваем его время на время отдыха, затем переходим к следующему шарику и снова отбираем минимальное время среди всех помощников.

Повторяем цикл, пока не наберется нужное количество надутых шариков

Блок-схема алгоритма



Программа (PascalABC.NET)

program zadacha17;
Const

Mmax=1000;

Nmax=20;

Tmax=100;

Ymax=100;

Zmax=1000;

var

m,n:integer; //m - число шариков и n - число помощников

i, j, k, min, time: integer;

done, next, t, y, z: array [0..Nmax] of integer;//храним полученные результаты

//next – массив, содержит момент окончания надувания помощником следущего шарика

//done – массив, содержит количество шариков, надутых помощником

//t - массив, содержит время надувания шариков помощниками

//y - массив, содержит время отдыха помощников

//z - массив, содержит число шариков, которые могут надуть помощники без перерыва

Begin

//Соединяемся с входным и выходным файлами

//ввод и вывод по умолчанию из файла и в файл

assign(input, 'input.txt');

reset(input);

assign(output, 'output.txt');

rewrite(output);

//заполняем массив с количеством помощников нулями

for i:=0 to Nmax do

done[i]:=0;

// Задаем начальное время работы

time := 0;

//Вводим данные из файла

read(m, n); //считываем число шариков и число помощников

if m<>0 then //требуется надувать шары

begin

for i := 1 to n do

begin

read(t[i], z[i], y[i]); //считываем показатели по каждому из помощников

next[i] := t[i];

end;

Close(input);

//заполняем массив с количеством помощников нулями

for i:=0 to Nmax do

done[i]:=0;

// Задаем начальное время работы

time := 0;

for i := 1 to m do

begin

//Ищем того, кто закончит раньше

min := MaxInt; //задаем минимум как самое большое целое

for j := 1 to n do

if next[j] < min then //если нашли меньше

begin

k := j; //запоминаем индекс

min := next[j]; //запоминаем минимум

end;

//Обновляем время работы

time := next[k];

//Добавляем помощнику новый шарик

inc(done[k]);

//Обновляем время окончания им работы

next[k] := next[k] + t[k];

//Учитываем отдых (проверяем, сколько шариков надул помощник

if done[k] mod z[k] = 0 then //если пора отдыхать

next[k] := next[k] + y[k]; //то увеличиваем общее время на время отдыха

end;

end;

//Выводим ответ

writeln(time); //выводим время

for i := 1 to n do

write(done[i], ' '); //выводим количество шариков, надутых каждым помощником

Close(output);

end.
Тесты:





написать администратору сайта