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

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

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

(PRO100 ЕГЭ) По каналу связи в течение N минут передаются данные измерений группы приборов. Каждую минуту передаётся результат измерения одного прибора, выбранного случайным образом. Определите максимальную разницу показаний одного прибора, между моментами передачи которых прошло не менее K минут.

Примечание: разница – это модуль разности двух значений.

Входные данные. Даны два входных файла (файл A и файл B), каждый из которых в первой строке содержит натуральное число N (2 ≤ N ≤ 10 000 000) – количество строк с данными, и натуральное число K (1 ≤ K ≤ N) – минимальный интервал времени между двумя показаниями одного прибора. Каждая из следующих N строк содержит два натуральных числа, не превышающих 100 000 000: номер прибора и результат измерений.

Пример входного файла:
5 3
1 15
2 10
2 35
1 0
2 30

При таких исходных данных максимально возможная разница равна 20 – это разница показаний, на второй и пятой минутах. Ответ: 20.

В ответе укажите два числа: сначала искомое значение для файла А, затем для файла B.

Решение

Самым простым решением является разделение данных по номерам приборов. Максимальный номер прибора во втором файле - 1000. Создадим массив, где для каждого прибора будем сохранять список переданных им показанием с указанием времени передачи. Для каждого прибора переберем все пары показаний и, если временной интервал между ними не менее k, проанализируем разность на максимальность.

Python

f = open("27-163b.txt")
n, k = map(int, f.readline().split())
a = [[] for i in range(1001)]
for i in range(1, n + 1):
    x, y = map(int, f.readline().split())
    a[x].append([i, y])
mx = 0
for z in a:
    for i in range(len(z) - 1):
        for j in range(i + 1, len(z)):
            if abs(z[i][0] - z[j][0]) >= k:
                mx = max(mx, abs(z[i][1] - z[j][1]))
print(mx)

PascalABC

type
    dataa = record
      time: Integer;
      val: Integer;
    end;
var
    n, k, max, i, j, x, y, z: Integer;
    d: dataa;
    a: array [1..1000] of array of dataa;
    f: TEXT;
begin
    for i := 1 to 1000 do
        a[i] := new dataa[0];
    Assign(f, '27-163b.txt');
    Reset(f);
    Readln(f, n, k);
    for i := 1 to n do
    begin
        Readln(f, x, y);
        d.time := i;
        d.val := y;
        a[x] := a[x] + Arr(d);
    end;
    max := 0;
    for z := 1 to 1000 do
        for i := 0 to a[z].Length - 2 do
            for j := i + 1 to a[z].Length - 1 do
                if abs(a[z][i].time - a[z][j].time) >= k then
                    if abs(a[z][i].val - a[z][j].val) > max then
                        max := abs(a[z][i].val - a[z][j].val);
    Writeln(max);
end.

C++

#include <iostream>
#include <fstream>
#include <vector>
struct dataa
{
    int time;
    int val;
};
using namespace std;
int main()
{
    ifstream f;
    f.open("27-163b.txt");
    int n, k;
    f >> n >> k;
    vector<dataa> a[1001];
    for (int i = 1; i <= n; i++)
    {
        int x;
        dataa t;
        t.time = i;
        f >> x >> t.val;
        a[x].push_back(t);
    }
    int max = 0;
    for (int z = 0; z <= 1000; z++)
        for (int i = 0; i < (int)a[z].size() - 1; i++)
            for (int j = i + 1; j < a[z].size(); j++)
                if (abs(a[z][i].time - a[z][j].time) >= k)
                    if (abs(a[z][i].val - a[z][j].val) >= max)
                        max = abs(a[z][i].val - a[z][j].val);
    cout << max << endl;
}

Можно обойтись и более простой структурой данных в виде двумерного массива, который отсортируем по номерам приборов (сортировка второго файла будет занимать некоторое время). Таким образом, показания одного прибора будут находится рядом. Последовательно просматривая данный массив, будем находить индексы самых первых и самых последних данных для каждого прибора, а потом так же перебирать все пары показаний одного прибора.

Python

f = open("27-163b.txt")
n, k = map(int, f.readline().split())
a = []
for i in range(1, n + 1):
    x, y = map(int, f.readline().split())
    a.append([x, i, y])
a.sort()
mx = 0
start = 0
finish = 0
while start != n:
    while finish < n and a[start][0] == a[finish][0]:
        finish += 1
    for i in range(start, finish - 1):
        for j in range(i + 1, finish):
            if abs(a[i][1] - a[j][1]) >= k:
                mx = max(mx, abs(a[i][2] - a[j][2]))
    start = finish
print(mx)

PascalABC

var
    n, k, max, min, start, finish, t, i, j: Integer;
    a: array [1..74190, 1..3] of Integer;
    f: TEXT;
begin
    Assign(f, '27-163b.txt');
    Reset(f);
    Readln(f, n, k);
    for i := 1 to n do
    begin
        a[i, 2] := i;
        Readln(f, a[i, 1], a[i, 3]);
    end;
    for i := 1 to n - 1 do
    begin
        min := i;
        for j := i + 1 to n do
            if a[j, 1] < a[min, 1] then
                min := j;
        if min <> i then
        begin
            t := a[i, 1];
            a[i, 1] := a[min, 1];
            a[min, 1] := t;
            t := a[i, 2];
            a[i, 2] := a[min, 2];
            a[min, 2] := t;
            t := a[i, 3];
            a[i, 3] := a[min, 3];
            a[min, 3] := t;
        end;
    end;
    max := 0;
    start := 1;
    finish := 1;
    while start <= n do
    begin
        while (finish <= n) and (a[start, 1] = a[finish, 1]) do
            finish := finish + 1;
        for i := start to finish - 2 do
            for j := i + 1 to finish - 1 do
                if (abs(a[i, 2] - a[j, 2]) >= k) and  (abs(a[i, 3] - a[j, 3]) > max) then
                    max := abs(a[i, 3] - a[j, 3]);
        start := finish;
    end;
    Writeln(max);
end.

C++

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    ifstream f;
    f.open("27-163b.txt");
    int n, k;
    f >> n >> k;
    int a[74190][3];
    for (int i = 1; i <= n; i++)
    {
        a[i][1] = i;
        f >> a[i][0] >> a[i][2];
    }
    for (int i = 0; i < n - 1; i++)
    {
        int min = i;

        for (int j = i + 1; j < n; j++)
            if (a[j][0] < a[min][0])
                min = j;
        if (min != i)
        {
            int t = a[i][0];
            a[i][0] = a[min][0];
            a[min][0] = t;
            t = a[i][1];
            a[i][1] = a[min][1];
            a[min][1] = t;
            t = a[i][2];
            a[i][2] = a[min][2];
            a[min][2] = t;
        }
    }
    int max = 0, start = 0, finish = 0;
    while (start != n)
    {
        while (finish < n && a[start][0] == a[finish][0])
            finish++;
        for (int i = start; i < finish - 1; i++)
            for (int j = i + 1; j < finish; j++)
                if (abs(a[i][1] - a[j][1]) >= k && abs(a[i][2] - a[j][2]) >= max)
                    max = abs(a[i][2] - a[j][2]);
        start = finish;
    }
    cout << max << endl;
}

Ответ

900 98964798

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

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

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

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