1 / 1 / 0 Регистрация: 07.10.2015 Сообщений: 37 |
|
1 |
|
Наибольшее произведение трех чисел22.11.2016, 22:39. Показов 32916. Ответов 11
Задача: В данном списке из n ≤ 105 целых чисел найдите три числа,произведение которых максимально. Ввод: -5 -30000 -12 Ввод: 1 2 3 Вопрос: как это реализовать? (использовать sortsorted от всего массива не получается, потому что тогда программа не проходит по времени)
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
22.11.2016, 22:39 |
Ответы с готовыми решениями: Вычислить произведение P кубов трех чисел a, b и c, если их сумма меньше нуля, произведение P модулей трех чисел a, b и c, если их сумма больше нуля Переменной d присвоить наибольшее из трех чисел, а переменной s наименьшее из трех чисел. Составить программу, которая переменной d… Найти наибольшее из трех чисел, используя процедуру нахождения наибольшего из 2 чисел. Если сумма трех различных чисел A, B, C равна 2, то наибольшее из этих чисел заменить наименьшим 11 |
273 / 132 / 44 Регистрация: 05.02.2015 Сообщений: 867 |
|
22.11.2016, 22:51 |
2 |
ну смотрите: вы задачу поиска максимума можете решить? можете. бежите по списку, и присваиваете переменной максимальное значение. а теперь также ищите 3 максимальных значения. т.е. 3 вспомогательных переменных и все. вот вам и o(n). Добавлено через 6 минут
1 |
438 / 430 / 159 Регистрация: 21.05.2016 Сообщений: 1,338 |
|
23.11.2016, 00:28 |
3 |
п.с. не смотря на то, что в цикле получается 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 как решение Решение
если по циклу пройтись 3 раза, то будет o(n^3). О(n^3) будет только если пройтись по списку n^3 раз. Если пройтись 3 раза, будет O(3n) = O(n) Добавлено через 1 час 47 минут
0 |
Vigi 628 / 468 / 179 Регистрация: 28.05.2012 Сообщений: 1,398 |
||||
23.11.2016, 07:34 |
6 |
|||
0 |
oldnewyear 438 / 430 / 159 Регистрация: 21.05.2016 Сообщений: 1,338 |
||||
23.11.2016, 07:47 |
7 |
|||
Сортировка списка не укладывается в требование к временной сложности O(n)
0 |
vint-81 охотник 1011 / 535 / 650 Регистрация: 29.09.2014 Сообщений: 1,083 |
||||||||
23.11.2016, 08:12 |
8 |
|||||||
Добавлено через 2 минуты
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 |
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).
0 |
bratsker 0 / 0 / 0 Регистрация: 15.11.2017 Сообщений: 1 |
||||
10.01.2018, 14:15 |
12 |
|||
при данных: 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 |
Помогаю со студенческими работами здесь Наибольшее из трех чисел Найти наибольшее из трех чисел Из трех чисел выбрать наибольшее решаю так: Найти наибольшее из трех чисел А,В,С. Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 12 |
Последние несколько задач показывали, что Python удобнее С++, но в этой задаче всё наоборот. Давайте посмотрим.
Если никакие мысли по поводу решения задачи не приходят в голову, то всегда можно написать самое простое решение и позапускать его на разных входных данных. Часто после такого можно найти закономерности или способы сокращения времени работы. В этой задаче можно было бы написать три вложенных цикла и находить максимум.
Можно пойти другим путём. Что было бы, если бы все числа были натуральными? Разумно предположить, что тогда максимальное произведение дали бы три самых больших числа. Супер! Мы уже близки к решению задачи.
Что же меняется, когда появляются отрицательные числа? Лишь то, что произведение двух отрицательных чисел даёт положительное число. То есть, если взять два самых маленьких числа, то произведение может получиться больше, чем у двух самых больших. И всё? Да. А если все числа будут отрицательными? Тогда произведение трёх чисел в любом случае будет отрицательным, а это значит, что нам надо выбрать минимальное по модулю, это можно получить минимальными по модулю множителями (то есть самыми большими из имеющихся чисел).
А в чём же тогда сложность задачи? В размере входных данных. Нам даётся до миллиона чисел. То есть входной файл может быть до 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
(Время: 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; | |
} |