670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
|
1 | |
Два указателя. Сложно09.05.2013, 00:50. Показов 8188. Ответов 19
Метки два указателя (Все метки)
Вот есть задача, с которой я не могу справиться, мне не нужен ваш код, а будет вполне достаточно словесного описания алгоритма или сути его работы. Решается он через 2 указателя, может потребуется сортировка. Никак не могу додуматься до алгоритма. Help.
Учтите, задача не простая, посмотрите на ограничения. ограничение времени на тест: 0.5 сек. ограничение памяти на тест: 262144 KB. Дана последовательность целых чисел a1, a2,..., an. Требуется найти такую пару (index, length), чтобы сумма чисел [aindex, aindex+1,..., aindex+length-1] была положительной. При этом length должно быть наибольшим возможным. Если ответов несколько, выберите ответ с меньшим index. В этой задаче последовательность ai будет задаваться в следующем виде: bi = (A · bi-1 + B) mod C, b0 = S, ai = X · bi + Y, где X, Y, A, B, C, S будут числами, заданными во входном файле. mod — это оператор взятия остатка. Генерацию последовательности делайте в 64-битном типе. Входные данные В первой строке содержится число n (1 ≤ n ≤ 5000000). Во второй строке записаны числа X, Y, A, B, C и S, разделенные пробелами (|X| ≤ 1000, |Y| ≤ 10^9, 0 < C ≤ 10^6, 0 ≤ A, B, S ≤ 10^6). Выходные данные Выведите числа index и length через пробел. Гарантируется, что length > 0. Ввод : 7 1 -2 3 4 5 6 Вывод : 3 5 Добавлено через 2 минуты Хотя, я не брезгую, код тоже не помешает.
0
|
09.05.2013, 00:50 | |
Ответы с готовыми решениями:
19
Выбор(будет ли сложно изучать два языка Си и СИ++) в функцию передается два строковых указателя Можно ли объявить два указателя на одну функцию? Как сравнить два указателя типа char? |
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
09.05.2013, 02:01 | 2 |
Ternsip, думаю что генерацию последовательности ускорить нельзя. Хотя bi напоминает конгруэнтную последовательность, и если можно бы было узнать ее период >_> Самому мне думать лень, так что по теме раз фича, два фича. Надеюсь, что это тебе как-то поможет.
1
|
267 / 189 / 33
Регистрация: 15.01.2011
Сообщений: 681
|
|
09.05.2013, 02:34 | 3 |
а тут точно так - bi = (A · bi-1 + B) mod C а не так bi = (A · b0-1 + B) mod C ?
0
|
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
|
|
09.05.2013, 06:08 | 4 |
еще раз повторю общую просьбу: публикуйте ссылку на тестер.
0
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
||||||
09.05.2013, 16:53 [ТС] | 5 | |||||
ssXXss, да, там b0 опечатка
salam, http://acm.sgu.ru/univer/probl... roblem=436 http://acm.sgu.ru/univer/ Добавлено через 8 секунд nonedark2008, спасибо Добавлено через 5 часов 21 минуту nonedark2008, первая фича http://stackoverflow.com/quest... equal-to-k Попытался по ней реализовать то, что там написано, вот что накатал, не работает, логика не ясна. arr у меня это массив частичных сумм
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
||||||
09.05.2013, 18:24 | 6 | |||||
Ternsip, не сильно проверял, но вроде работает:
1
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
|
09.05.2013, 18:29 [ТС] | 7 |
nonedark2008, у вас сейчас квадратичный, медленный алгоритм, он не подходит, по времени не пройдёт
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
09.05.2013, 18:53 | 8 |
Ternsip, ок, увидел. Все из-за двойного цикла. Я его писал без учета отсортированности массива. А так, подойдет та часть, что вы сами написал... Тогда удастся избежать двойного цикла, а значит и сложность будет nlogn.
Добавлено через 16 минут А алгоритм достаточно понятен. Мы для каждого префикса в массиве находим префиксы больший либо равный текущему и берем тот, у которого индекс будет самым большим. Если идекс одного префикса больше индекса другого и второй префикс >= первому, то сумма элементов между индексов будет >= 0. Выбирая префикс с самым большим индексом мы выбираем самую длинную цепочку. А дальше, просто ижем максимум разности maxInd и ind - это будет длина самой длинной цеопчки, сумма которой больше нуля.
0
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
||||||
09.05.2013, 19:11 [ТС] | 9 | |||||
nonedark2008, вот переписал под свой лад
nonedark2008, щас затещу Добавлено через 2 минуты nonedark2008, 2/90 видимо сдесь какой то архикосяк, сейчас попробую понять вашу идею, пока сам не допёр ещё Добавлено через 36 секунд nonedark2008, кстати, TL очень много за NlogN не проходит решение Добавлено через 1 минуту nonedark2008, может из-за make_pair() так медленно ? по идее N Log N должно за 0.5 секунды проходить
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
09.05.2013, 19:12 | 10 |
0
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
|
09.05.2013, 19:20 [ТС] | 11 |
nonedark2008, нет, тут всё ок
0
|
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
|
|
09.05.2013, 19:20 | 12 |
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
09.05.2013, 19:34 | 13 |
Ternsip, в вашем решении больше всего жрет сортировка - как и должно быть. Чаще всего вызывается оператор сравнения в сортировке, что плохо, т.к. для сравнения двух чисел вызывается отдельный метод.
Так что лучше написать свой алгоритм сортировки, отказаться от использования векторов в пользу массивов, отказаться от использования потокового ввода/вывода в пользу printf/scanf. Чтобы самому проверять что жрет больше всего - нужно использовать анализатор производительности, например он встроен в VS, а также он есть в утилитах от Intel. Добавлено через 5 минут Ternsip, кстати, ты вроде забыл про условие, что если встретятся одинаковые ответы, то нужно выбрать с наименьшим индексом. Так что в последнем цыкле еще нужно проверять на >=, а внутри выбирать с наименьшим индексом.
0
|
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
|
|
09.05.2013, 20:00 | 14 |
0
|
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
|
|
09.05.2013, 20:05 | 15 |
Ну хоть по оценке сложности судить о точном времени, но на моем ноуте при максимальном размере n программа выполняется примерно за 0.57 секунды, так что после оптимизации будет самое то!
0
|
194 / 174 / 30
Регистрация: 10.07.2012
Сообщений: 800
|
|
09.05.2013, 20:08 | 16 |
во-первых, извините за прямоту, ваш ноут мало кого интересует. если его тех параметры соответствуют параметрам тестера, то ок, конечно...
Добавлено через 37 секунд вообще разговор не об этом. от человека хотят, чтобы он писал оптимальные решения...
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|||||||||||
10.05.2013, 20:15 | 17 | ||||||||||
Дайте, пожалуйста, рабочую ссылку на задачу. Или, если возможно, не могли бы Вы уточнить формулы. Потому что при тех что есть, используя данные из примера, получается последовательность: 4 0 -2 2 -1 0 -2, а это не соответствует ответу. А так вот один из вариантов:
Внутренний цикл можно немного оптимизировать, чтобы избежать возможных лишних итераций.
0
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
||||||
10.05.2013, 20:57 [ТС] | 18 | |||||
Toshkarik, Вы не правы, последовательность получается такая : 0 -2 2 -1 0 -2 2, да и ответ верен: c 3-й позиции в ровно 5 чисел, сумма = 1.
я уже давал ссылку Два указателя. Сложно, ссылка рабочая, туда доступ только из Саратова Добавлено через 3 минуты Toshkarik, я уже делал квадратичный алгоритм, он никак не пройдёт по времени с такими ограничениями!!
Toshkarik, послдний код, что я привёл работает всегда правильно, но по времени не укладывается в 0.5 секунды, потому что это лобовая реализация за О(n^2) Добавлено через 1 минуту а тут нужен алгоритм за О(n), ну может, в самом крайнем случае, если я что то не понял, то за О(Nlogn) Добавлено через 11 минут Toshkarik, кстати sum[ 0 ] = 0;
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
10.05.2013, 21:46 | 19 |
По моей логике первая сумма равна первому элементу последовательности, то есть sum[ 0 ] = a0, sum[ 1 ] = a0 + a1 и тд. Плюс все находится в одном основном цикле, ну и проверка во вложенном цикле ( if ( i - j ) >= length ) позволяет избегать поиска когда уже есть вариант длины с бОльшим значением, чем осталось элементов для поиска.
Странно, даже в ручную посчитать - первый элемент не равен нулю: a0 = X * b0 + Y = 1 * 6 + ( -2 ), поправьте меня, пожалуйста, может что то упускаю.
0
|
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
|
||||||
11.05.2013, 00:27 [ТС] | 20 | |||||
b1 = (a * b0 + b) % c = (3 * 2 + 6) % 5 = 2
a1 = x * b1 + y = 1 * 2 + (-2) = 0 Вы не правильно поняли задание. Последовательность нумеруется с единицы, но как вы храните, это не важно. Но не в этом суть, а в том, что никто не может придумать алгоритм с двумя указателями, работающий за О(n), т.е. линейно (на этом форуме). У меня несколько знакомых первокуров её уже сдали. А это на асимптотику не влияет, ваш алгоритм всё равно за О(n^2), как и мой, в моём есть ровно всё то, что вы сказали. Я уже проверял не пройдёт он. Добавлено через 59 минут Всё-таки спросил у друга, который сделал. Он помог. Тема закрыта. Вот код, работает он за О(n), жалко, конечно, что никто не помог, но всё равно спасибо
0
|
11.05.2013, 00:27 | |
11.05.2013, 00:27 | |
Помогаю со студенческими работами здесь
20
Почему увеличение указателя на sizeof(тип) не тождественно инкременту этого же указателя? Создание указателя на экземпляр класса, описанного после объявления указателя Преобразование кода без указателя в код с использованием указателя Как сделать функцию от указателя на класс и указателя на метод? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |