№№ заданий Пояснения Ответы Ключ Добавить инструкцию Критерии
Источник Раздел кодификатора ФИПИ Справка
PDF-версия PDF-версия (вертикальная) PDF-версия (крупный шрифт) PDF-версия (с большим полем) Версия для копирования в MS Word
Задания
Задание 27 № 13584

Дан набор из N целых положительных чисел. Необходимо выбрать из набора произвольное количество чисел так, чтобы их сумма была как можно больше и при этом не делилась на 8. В ответе нужно указать количество выбранных чисел и их сумму, сами числа выводить не надо. Если получить нужную сумму невозможно, считается, что выбрано 0 чисел и их сумма равна 0.

Напишите эффективную по времени и по памяти программу для решения этой задачи.

Программа считается эффективной по времени, если при увеличении количества исходных чисел N в k раз время работы программы увеличивается не более чем в k раз.

Программа считается эффективной по памяти, если память, необходимая для хранения всех переменных программы, не превышает 1 килобайт и не увеличивается с ростом N.

Максимальная оценка за правильную (не содержащую синтаксических ошибок и дающую правильный ответ при любых допустимых входных данных) программу, эффективную по времени и по памяти, — 4 балла.

Максимальная оценка за правильную программу, эффективную только по времени или только по памяти, — 3 балла.

Максимальная оценка за правильную программу, не удовлетворяющую требованиям эффективности, — 2 балла.

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

Перед текстом программы кратко опишите алгоритм решения. Укажите использованный язык программирования и его версию.

Описание входных и выходных данных

В первой строке входных данных задаётся количество чисел N (1 ≤ N ≤ 1000).

В каждой из последующих N строк записано одно натуральное число, не превышающее 10 000.

Пример входных данных:

3

1

2

5

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

Пример выходных данных для приведённого выше примера входных данных:

2 7

В данном случае из предложенного набора нужно выбрать два числа (2 и 5), их сумма равна 7.

Решение.

Если сумма всех данных чисел не кратна 8, нужно просто взять все числа.

Если сумма кратна 8, нужно удалить из неё минимально возможный элемент — наименьшее из заданных чисел, не кратное 8. Если таких чисел нет (все числа в наборе кратны 8), то получить требуемую сумму невозможно, в этом случае по условию задачи ответ считается равным нулю.

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

Ниже приведена реализующая этот алгоритм программа на языке Паскаль (использована версия PascalABC)

 

const

d=8; {делитель}

amax = 10000; {максимально возможное число}

var

N: integer; {количество чисел}

a: integer; {очередное число}

s: integer; {сумма}

mn: integer; {минимальное число, не кратное d}

k: integer; {количество выбранных чисел}

i: integer;

begin

readln(N);

s := 0;

mn := amax+1;

for i:=1 to N do begin

readln(a);

s := s+a;

if (a mod d <> 0) and (a < mn)

then mn := a;

end;

if s mod d <> 0 then k := N

else if mn <= amax then begin

k := N-1;

s := s - mn;

end

else begin

k := 0;

s := 0;

end;

writeln(k, ' ', s);

end.

Пример правильной, но неэффективной программы на языке Паскаль.

var

    N: integer; {количество чисел}

    val: integer; {сумма выбранного количества чисел}

    a: array [1..1000] of integer;

    count: integer; {количество выбранных чисел}

    i, j, k: integer;

begin

    readln(N);

    val := 0;

    for i:=1 to N do read(a[i]);

    for i:=1 to N do val:=val+a[i];

    for i:=1 to N-1 do

        for j:=1 to N-i do

            if a[j] < a[j+1] then begin

                k := a[j];

                a[j] := a[j+1];

                a[j+1] := k;

            end;

    count := N;

    while (val mod 8 = 0) do begin

        if a[count] mod 8 <> 0 then

            val := val - a[count];

        count := count - 1;

        if count = 0 then begin

            val := 0;

            break;

        end;

    end;

    writeln(count, ' ', val);

end.

· ·