Как найти наибольшее произведение трех чисел

1 / 1 / 0

Регистрация: 07.10.2015

Сообщений: 37

1

Наибольшее произведение трех чисел

22.11.2016, 22:39. Показов 32916. Ответов 11


Студворк — интернет-сервис помощи студентам

Задача: В данном списке из n ≤ 105 целых чисел найдите три числа,произведение которых максимально.
Решение должно иметь сложность O(n), где n – размер списка.
Выведите три искомых числа в любом порядке.
Примеры:
Ввод: 3 5 1 7 9 0 9 -3 10
Вывод: 10 9 9

Ввод: -5 -30000 -12
Вывод: -5 -12 -30000

Ввод: 1 2 3
Вывод: 3 2 1

Вопрос: как это реализовать? (использовать sortsorted от всего массива не получается, потому что тогда программа не проходит по времени)



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

22.11.2016, 22:39

Ответы с готовыми решениями:

Вычислить произведение P кубов трех чисел a, b и c, если их сумма меньше нуля, произведение P модулей трех чисел a, b и c, если их сумма больше нуля
Вычислить произведение P кубов трех чисел a, b и c, если их сумма меньше нуля,
произведение P…

Переменной d присвоить наибольшее из трех чисел, а переменной s наименьшее из трех чисел.
Написать код программы с помощью оператора if в С++

Составить программу, которая переменной d…

Найти наибольшее из трех чисел, используя процедуру нахождения наибольшего из 2 чисел.
10. Найти наибольшее из трех чисел, используя процедуру нахождения наибольшего из 2 чисел.

Если сумма трех различных чисел A, B, C равна 2, то наибольшее из этих чисел заменить наименьшим
Если сумма трех различных чисел A,B,C равна 2, то наибольшее из этих чисел заменить наименьшим,…

11

273 / 132 / 44

Регистрация: 05.02.2015

Сообщений: 867

22.11.2016, 22:51

2

ну смотрите: вы задачу поиска максимума можете решить? можете. бежите по списку, и присваиваете переменной максимальное значение. а теперь также ищите 3 максимальных значения. т.е. 3 вспомогательных переменных и все. вот вам и o(n).

Добавлено через 6 минут
п.с. не смотря на то, что в цикле получается 3 условия, o(n) сохраняется, потому что в каждой итерации верной может быть только одно: если элемент больше максимального, максимальное = элемент. иначе, если элемент больше второго максимального, то второе по максимальное = элементу. если третье меньше элемента, третье = элементу.



1



438 / 430 / 159

Регистрация: 21.05.2016

Сообщений: 1,338

23.11.2016, 00:28

3

Цитата
Сообщение от minore
Посмотреть сообщение

п.с. не смотря на то, что в цикле получается 3 условия, o(n) сохраняется, потому что в каждой итерации верной может быть только одно: если элемент больше максимального, максимальное = элемент. иначе, если элемент больше второго максимального, то второе по максимальное = элементу. если третье меньше элемента, третье = элементу.

Можно по циклу 3 раза пройтись, все равно O(n) будет



0



273 / 132 / 44

Регистрация: 05.02.2015

Сообщений: 867

23.11.2016, 00:43

4

если по циклу пройтись 3 раза, то будет o(n^3).



0



oldnewyear

438 / 430 / 159

Регистрация: 21.05.2016

Сообщений: 1,338

23.11.2016, 03:43

5

Лучший ответ Сообщение было отмечено Mon4ik как решение

Решение

Цитата
Сообщение от minore
Посмотреть сообщение

если по циклу пройтись 3 раза, то будет o(n^3).

О(n^3) будет только если пройтись по списку n^3 раз. Если пройтись 3 раза, будет O(3n) = O(n)

Добавлено через 1 час 47 минут

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
numbers = [1,9,-10,-20,-8, 7, 14, 0, 20, 20, -20]
 
if len(numbers) < 3:
    print ('List should contain at least 3 numbers')
    exit (0)
 
nmax1 = numbers[0]
nmin1 = numbers[0]
 
for n in numbers:
    if n > nmax1: nmax1 = n
    if n < nmin1: nmin1 = n
 
numbers.remove(nmax1)
numbers.remove(nmin1)
nmax2 = numbers[0]
nmin2 = numbers[0]
 
for n in numbers:
    if n > nmax2: nmax2 = n
    if n < nmin2: nmin2 = n
 
numbers.remove(nmax2)
 
nmax3 = numbers[0]
 
for n in numbers:
    if n > nmax3: nmax3 = n
 
p1 = nmin1*nmin2*nmax1
p2 = nmax1*nmax2*nmax3
 
if p1 > p2:
    print (nmin1, nmin2, nmax1)
else:
    print (nmax1, nmax2, nmax3)



0



Vigi

628 / 468 / 179

Регистрация: 28.05.2012

Сообщений: 1,398

23.11.2016, 07:34

6

Python
1
print(*sorted(map(int, input().split()))[::-1][:3])



0



oldnewyear

438 / 430 / 159

Регистрация: 21.05.2016

Сообщений: 1,338

23.11.2016, 07:47

7

Цитата
Сообщение от Vigi
Посмотреть сообщение

Python
1
print(*sorted(map(int, input().split()))[::-1][:3])

Сортировка списка не укладывается в требование к временной сложности O(n)



0



vint-81

охотник

1011 / 535 / 650

Регистрация: 29.09.2014

Сообщений: 1,083

23.11.2016, 08:12

8

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
numbers = [1,9,-10,-20,-8, 7, 14, 0, 20, 20, -20]
 
max_1 = max(numbers[0],numbers[1])
min_1 = min(numbers[0],numbers[1])
max_2 = numbers[0]*numbers[1]
min_2 = numbers[0]*numbers[1]
max_3 = numbers[0]* numbers[1]*numbers[2]
 
for x in numbers[2:]:
    max_3 = max(max_3, x*max_2, x*min_2)
        max_2 = max(max_2, x*max_1, x*min_1)
        min_2 = min(min_2, x*max_1, x*min_1)
        max_1 = max(max_1,x)
        min_1 = min(min_1,x)
 
print(max_3)

Добавлено через 2 минуты

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
numbers = [1,9,-10,-20,-8, 7, 14, 0, 20, 20, -20]
 
max_1 = max(numbers[0],numbers[1])
min_1 = min(numbers[0],numbers[1])
max_2 = numbers[0]*numbers[1]
min_2 = numbers[0]*numbers[1]
max_3 = numbers[0]* numbers[1]*numbers[2]
 
for x in numbers[2:]:
        max_3 = max(max_3, x*max_2, x*min_2)
        max_2 = max(max_2, x*max_1, x*min_1)
        min_2 = min(min_2, x*max_1, x*min_1)
        max_1 = max(max_1,x)
        min_1 = min(min_1,x)
 
print(max_3)



0



1 / 1 / 0

Регистрация: 07.10.2015

Сообщений: 37

23.11.2016, 21:46

 [ТС]

9

oldnewyear, спасибо, у вас самый понятный код) Только он не срабатывает для 2 и 3 примеров. Не нравится, что в 25 строке индекс = 0. Почему?



0



438 / 430 / 159

Регистрация: 21.05.2016

Сообщений: 1,338

23.11.2016, 22:59

10

Цитата
Сообщение от Mon4ik
Посмотреть сообщение

oldnewyear, спасибо, у вас самый понятный код) Только он не срабатывает для 2 и 3 примеров. Не нравится, что в 25 строке индекс = 0. Почему?

Надо сделать проверку в начале – если в списке только 3 числа, вывести их и завершить программу



0



0 / 0 / 0

Регистрация: 29.09.2017

Сообщений: 1

29.09.2017, 14:30

11

Достаточно найти три наибольших элемента (обзовём их m1, m2, m3) и два наименьших (n1, n2).
Тогда наибольшее произведение будет либо m1 * m2 * m3 либо m1 * n1 * n2.
Наибольшие/наименьшие элементы можно выбрать за один проход – O(n).



0



bratsker

0 / 0 / 0

Регистрация: 15.11.2017

Сообщений: 1

10.01.2018, 14:15

12

Цитата
Сообщение от Vigi
Посмотреть сообщение

Python
1
print(*sorted(map(int, input().split()))[::-1][:3])

при данных: 1 9 -10 -20 -8 7 14 0 20 20 -20 должны получить: -20 -20 20, а сортировка выдает 20 20 14.
не подходит.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

10.01.2018, 14:15

Помогаю со студенческими работами здесь

Наибольшее из трех чисел
Составить функцию, которая получает три аргумента х, y, и z, и возвращает как результат наибольшее…

Найти наибольшее из трех чисел
Помогите пожалуйста решить.
Даны три числа. Найти наибольшее число из них. Вывести результат на…

Из трех чисел выбрать наибольшее
Надо из трех чисел выбрать наибольшее

решаю так:
var a,b,c : integer;
begin
while a&gt;b and…

Найти наибольшее из трех чисел А,В,С.
Найти наибольшее из трех чисел А,В,С.

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

12

Последние несколько задач показывали, что Python удобнее С++, но в этой задаче всё наоборот. Давайте посмотрим.

Условие задачи с сайта acmp.ru
Условие задачи с сайта acmp.ru

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

Можно пойти другим путём. Что было бы, если бы все числа были натуральными? Разумно предположить, что тогда максимальное произведение дали бы три самых больших числа. Супер! Мы уже близки к решению задачи.

Что же меняется, когда появляются отрицательные числа? Лишь то, что произведение двух отрицательных чисел даёт положительное число. То есть, если взять два самых маленьких числа, то произведение может получиться больше, чем у двух самых больших. И всё? Да. А если все числа будут отрицательными? Тогда произведение трёх чисел в любом случае будет отрицательным, а это значит, что нам надо выбрать минимальное по модулю, это можно получить минимальными по модулю множителями (то есть самыми большими из имеющихся чисел).

А в чём же тогда сложность задачи? В размере входных данных. Нам даётся до миллиона чисел. То есть входной файл может быть до 8Мб (7 цифр в числе, знак минус и пробел). И это создаёт две проблемы: объём используемой памяти и время считывания такого количества данных.

Если на Python’е использовать простой список или кортеж, и даже если посылать решение на PyPy, то пройти ограничение по памяти очень сложно. На странице лучших попыток видно, что только 4 человек смогли это сделать. В то время как на С++ можно либо использовать scanf, либо известную каждому олимпиадному программисту на С++ “магическую строку”:

Ускорение потокового ввода на С++
Ускорение потокового ввода на С++

После такого можно вообще не заботиться о скорости в этой задаче, и даже не обращать внимание на асимптотику решения и использовать сортировку:

Полное решение на С++
Полное решение на С++

Главное не забывайте про переполнение типов. Здесь у нас сами числа до 30000, но их произведение уже не помещается в тип int, поэтому в произведении добавлен множитель 1LL (единица типа long long), и тогда компилятор всё произведение считает в типе данных long long.

Конечно же, использование сортировки для поиска трёх максимальных чисел – это излишество, и правильнее находить их за один проход по массиву. Хммм… один проход, а это значит, что нам не надо хранить все данные в оперативной памяти.

Заведём переменные для всех необходимых нам значений:

Объявление переменных для трёх максимальных и двух минимальных значений
Объявление переменных для трёх максимальных и двух минимальных значений

И будем считывать и сразу обрабатывать входные данные:

Считывание данных
Считывание данных

Как же найти три максимальных числа? Элементарно. Мы поддерживанием ТОП-3. Если встретили число, которое больше текущего максимума, то тогда обновится весь топ. Но нельзя забывать, что число может быть меньше максимального, но превышать второй (или третий) максимум, тогда обновится соответствующая часть топа.

Поиск трёх максимальных чисел
Поиск трёх максимальных чисел

Аналогично поступаем с поиском двух минимальных чисел:

Поиск двух минимальных чисел
Поиск двух минимальных чисел

Ну, а вычисление итогового ответа остаётся почти без изменений:

Вычисление и вывод ответа
Вычисление и вывод ответа

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

Результаты работы обоих решений
Результаты работы обоих решений

Сила С++ в его скорости. А если вам удалось сдать задачу на Python, то поделитесь секретом в комментариях, всем будет интересно.

Предыдущий выпуск: Задача 131. Перепись

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

There are some catches on this problem, in a list involving both positive and negative int, the largest combination could be the smallest negative, second smallest negative value,largest positive value or largest positive value, second largest positive value and third largest value;

For example, a list of -5,-1,1,2,3 should return 15, but when there are only negative values in the list, this does Not work, instead of picking the smallest negative integers, the larges combination is actually the three largest negative values, for example: -5,-4,-3,-2,-1 should return -6. the easy way to code this would be just store the three largest positive values(consider 0 as positive),

Three smallest negative values and three largest negative values as we going through the array, then we try all the combinations of these nine numbers and get the max. this only takes O(n) time and O(1) space.

Гасан Мурадов



Ученик

(132),
на голосовании



7 лет назад

Голосование за лучший ответ

Татьяна Шеховцова

Искусственный Интеллект

(269946)


7 лет назад

Выбрать 3 самых больших и перемножить

Jurijus ZaksasИскусственный Интеллект (392271)

7 лет назад

Пусть даны числа -20 -10 1 2 3
Логично, что самое большое число -20*-10*3=600
Но по твоему алгоритму это 1*2*3=6
Что как-то немного не совсем правильно.

Татьяна Шеховцова
Искусственный Интеллект
(269946)
Тогда то же самое по модулю + следить чтобы отрицательных было чётное кол-во
(Уже лет 5 задачи подобного типа не встречались, забывается однако)

johnsilver

Просветленный

(22275)


7 лет назад

наибольшее число будет из произведения 3-х наибольших чисел.
сортируй, бери 3 крайних с нужной стороны

Jurijus ZaksasИскусственный Интеллект (392271)

7 лет назад

Не работает для отрицательных чисел.

johnsilver
Просветленный
(22275)
ну таки да, но я же не должен все делать за [s]головотяпа [/s] автора вопроса

Jurijus Zaksas

Искусственный Интеллект

(392271)


7 лет назад

Перебрать все варианты рекуррентной функцией.

Иван Сигаев

Искусственный Интеллект

(138086)


7 лет назад

max=A[0]*A[1]*A[2];
for(int i=0;i < N; i++){
for(int j=1;j < N; j++){
if(j==i)continue;
for(int k=2;k < N;k++){
if(k==i)continue;
if(k==j)continue;
if(max<A[i]*A[j]*A[k])max=A[i]*A[j]*A[k];
}
}
}

Похожие вопросы


This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

Show hidden characters

(Время: 1 сек. Память: 16 Мб Сложность: 38%)
Дано N целых чисел. Требуется выбрать из них три таких числа, произведение которых максимально.
Входные данные
Во входном файле INPUT.TXT записано сначала число N — количество чисел в последовательности (3 ≤ N ≤ 106). Далее записана сама последовательность: N целых чисел, по модулю не превышающих 30000.
Выходные данные
В выходной файл OUTPUT.TXT выведите значение наибольшего произведения искомых трех чисел.
#include<bits/stdc++.h>
using namespace std;
int main() {
freopen(“input.txt”, “r”, stdin);
//freopen(“output.txt”, “w”, stdout);
ios_base::sync_with_stdio(false);
int n;
long long ans, e, r;
cin >> n;
vector <int> v(n);
for (int i = 0; i < n; i++){
cin >> v[i];
}
sort(v.begin(), v.end());
r = 1LL*v[n – 3] * v[n – 2] * v[n – 1];
e = 1LL*v[n – 1] * v[0] * v[1];
if (r > e)
ans = r;
else
ans = e;
cout << ans;
return 0;
}

Добавить комментарий