Программное решение задач ЕГЭ по информатике

Задача 6667. Источник: Поляков. Задание КИМ 26

Страница задачи 6667

(Е. Джобс) В волшебной стране живут гномы, которые любят варить зелья в магических котлах. Они имеют очень тонкую душевную организацию и стесняются стоять рядом с кем-то за соседним котлом. Гном всегда выбирает свободный котел с наименьшим номером, рядом с которым никто не стоит. Если это невозможно, но свободные котлы есть, гном выбирает свободный котел с наименьшим номером. Гном варит свою порцию зелья 6 минут, после чего уходит с поляны. В котле, который он освободил, другой гном сразу же может варить своё зелье.

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

Входные данные представлены в файле 26-127.txt следующим образом. Первая строка входного файла содержит натуральное число N (1 ≤ N ≤ 10000) – количество гномов, желающих сварить зелье. В каждой из следующих N строк записано время в минутах от начала суток, когда гном подошел к поляне с котлами – натуральное число, не превышающее 1433. Строки в файле (кроме первой) расположены в случайном порядке.

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

Пример входного файла:
6
6
8
10
14
20
22

При таких исходных данных необходимо 3 котла. Зелье без неудобств смогут сварить два гнома, пришедших через 20 и 22 минуты после полуночи. Распределение котлов: 1 котёл: 6-12, 14-20, 20-26; 2 котёл: 10-16; 3 котёл: 8-14, 22-28. Ответ: 3 2.

Решение

Считываем данные в массив/список и сортируем в порядке возрастания. Создадим массив/список/вектор busy, где будем хранить информацию о времени освобождения занятых котлов. Перед обработкой информации об очередном гноме удаляем из этого списка все записи об освободившихся котлах, т.е. время освобождения которых меньше или равно времени визита обрабатываемого гнома. После этого добавляем информацию о времени освобождения очередного котла. Максимальный размер busy будет минимальным количеством необходимых котлов.

Для получения числа гномов, сваривших зелье в комфорте, создадим массив/список pots с количеством элементов на два больше, чем найденное минимальное количество (слева первого котла и справа последнего будут "виртуальные" котлы для упрощения кода). Каждая запись будет содержать время освобождения данного котла и флаговое значение, варил ли гном это зелье в комфорте. Организуем цикл по количеству минут, когда варились все зелья. В этом цикле находим котлы, которые освободились в данную минуту и, если флаг комфорта сохранился, увеличиваем счетчик. После этого для каждого гнома, начавшего варить зелье в эту минуту ищем подходящий котел. Сначала ищем котел, у которого соседи свободны и прописываем для этого котла время освобождения и устанавливаем флаг комфорта. Если комфортного котла не нашлось, ищем первый свободный котел, прописываем ему время освобождения, а флаг комфорта сбрасываем не только у данного котла, но и у соседних котлов.

Python

  1. f = open('26-127.txt')
  2. n = int(f.readline())
  3. a = [int(f.readline()) for x in range(n)]
  4. a.sort()
  5. maxk = 0;
  6. busy = []
  7. for i in a:
  8. j = 0
  9. while j < len(busy):
  10. if busy[j] <= i:
  11. del busy[j]
  12. else:
  13. j += 1
  14. busy.append(i + 6)
  15. maxk = max(maxk, len(busy))
  16. pots = [[-1, True] for i in range(maxk + 2)]
  17. j = 0
  18. k = 0
  19. for i in range(a[n - 1] + 7):
  20. for m in range(1, maxk + 1):
  21. if pots[m][0] == i and pots[m][1]:
  22. k += 1
  23. while j < n and a[j] == i:
  24. pot = 0
  25. for m in range(1, maxk + 1):
  26. if pots[m - 1][0] <= i and pots[m][0] <= i and pots[m + 1][0] <= i:
  27. pots[m][0] = i + 6
  28. pots[m][1] = True
  29. pot = m
  30. break
  31. if pot == 0:
  32. for m in range(1, maxk + 1):
  33. if pots[m][0] <= i:
  34. pots[m][0] = i + 6
  35. pots[m][1] = False
  36. pots[m - 1][1] = False
  37. pots[m + 1][1] = False
  38. break
  39. j += 1
  40. print(maxk, k)

PascalABC

  1. var
  2. n, min, maxk, k, i, j, m, pot, t: Integer;
  3. a: array [1..5000] of Integer;
  4. busy: array of Integer = new integer[0];
  5. pots: array [0..100, 1..2] of Integer;
  6. f: TEXT;
  7. begin
  8. Assign(f, '26-127.txt');
  9. Reset(f);
  10. Readln(f, n);
  11. for i := 1 to n do
  12. Readln(f, a[i]);
  13. for i := 1 to n - 1 do
  14. begin
  15. min := i;
  16. for j := i + 1 to n do
  17. if a[j] < a[min] then
  18. min := j;
  19. if min <> i then
  20. begin
  21. t := a[i];
  22. a[i] := a[min];
  23. a[min] := t;
  24. end;
  25. end;
  26. maxk := 0;
  27. for i := 1 to n do
  28. begin
  29. j := 0;
  30. while j < busy.Length do
  31. if busy[j] <= a[i] then
  32. busy := busy[:j] + busy[j + 1:]
  33. else
  34. j := j + 1;
  35. busy := busy + Arr(a[i] + 6);
  36. if busy.Length > maxk then
  37. maxk := busy.Length;
  38. end;
  39. for i := 0 to maxk + 1 do
  40. begin
  41. pots[i, 1] := -1;
  42. pots[i, 2] := 1;
  43. end;
  44. j := 1;
  45. k := 0;
  46. for i := 0 to a[n] + 6 do
  47. begin
  48. for m := 1 to maxk do
  49. if (pots[m][1] = i) and (pots[m][2] = 1) then
  50. k := k + 1;
  51. while (j <= n) and (a[j] = i) do
  52. begin
  53. pot := 0;
  54. for m := 1 to maxk do
  55. if (pots[m - 1][1] <= i) and (pots[m][1] <= i) and (pots[m + 1][1] <= i) then
  56. begin
  57. pots[m][1] := i + 6;
  58. pots[m][2] := 1;
  59. pot := m;
  60. break;
  61. end;
  62. if pot = 0 then
  63. for m := 1 to maxk do
  64. if (pots[m][1] <= i) then
  65. begin
  66. pots[m][1] := i + 6;
  67. pots[m][2] := 0;
  68. pots[m - 1][2] := 0;
  69. pots[m + 1][2] := 0;
  70. break;
  71. end;
  72. j := j + 1
  73. end;
  74. end;
  75. Writeln(maxk, ' ', k);
  76. end.

C++

  1. #include <iostream>
  2. #include <vector>
  3. #include <fstream>
  4. using namespace std;
  5. int main()
  6. {
  7. ifstream f;
  8. f.open("26-127.txt");
  9. int n;
  10. f >> n;
  11. int a[5000];
  12. for (int i = 0; i < n; i++)
  13. f >> a[i];
  14. for (int i = 0; i < n - 1; i++)
  15. {
  16. int min = i;
  17. for (int j = i + 1; j < n; j++)
  18. if (a[j] < a[min])
  19. min = j;
  20. if (min != i)
  21. {
  22. int t = a[i];
  23. a[i] = a[min];
  24. a[min] = t;
  25. }
  26. }
  27. int maxk = 0;
  28. vector<int> busy;
  29. for (int i = 0; i < n; i++)
  30. {
  31. int j = 0;
  32. while (j < busy.size())
  33. if (busy[j] <= a[i])
  34. busy.erase(busy.begin() + j);
  35. else
  36. j++;
  37. busy.push_back(a[i] + 6);
  38. if (busy.size() > maxk)
  39. maxk = busy.size();
  40. }
  41. int pots[100][2];
  42. for (int i = 0; i <= maxk + 1; i++)
  43. {
  44. pots[i][0] = -1;
  45. pots[i][1] = 1;
  46. }
  47. int j = 0;
  48. int k = 0;
  49. for (int i = 0; i <= a[n - 1] + 6; i++)
  50. {
  51. for (int m = 1; m <= maxk; m++)
  52. if (pots[m][0] == i && pots[m][1] == 1)
  53. k++;
  54. while (j < n && a[j] == i)
  55. {
  56. int pot = 0;
  57. for (int m = 1; m <= maxk; m++)
  58. if (pots[m - 1][0] <= i && pots[m][0] <= i && pots[m + 1][0] <= i)
  59. {
  60. pots[m][0] = i + 6;
  61. pots[m][1] = 1;
  62. pot = m;
  63. break;
  64. }
  65. if (pot == 0)
  66. for (int m = 1; m <= maxk; m++)
  67. if (pots[m][0] <= i)
  68. {
  69. pots[m][0] = i + 6;
  70. pots[m][1] = 0;
  71. pots[m - 1][1] = 0;
  72. pots[m + 1][1] = 0;
  73. break;
  74. }
  75. j++;
  76. }
  77. }
  78. cout << maxk << " " << k << endl;
  79. }

Ответ

38 2460

Отправить замечание по решению

Код по которому имеется замечание:

Ваш вариант кода:

Комментарий: