СДАМ ГИА: РЕШУ ЕГЭ
Образовательный портал для подготовки к экзаменам
Информатика
≡ информатика
сайты - меню - вход - новости




Задания
Версия для печати и копирования в MS Word
Задание 27 № 13557

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

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

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

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

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

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

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

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

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

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

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

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

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

3

1

2

3

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

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

2 5

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

Решение.

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

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

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

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

 

const

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

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 6 = 0) do begin

        if a[count] mod 6 <> 0 then

            val := val - a[count];

        count := count - 1;

        if count = 0 then begin

            val := 0;

            break;

        end;

    end;

    writeln(count, ' ', val);

end.

Источник: Тренировочная работа по ИНФОРМАТИКЕ 11 класс 30 сентября 2016 года Вариант ИН10103