powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / все комбинации из 3-х элементов: алгоритм поиска
57 сообщений из 57, показаны все 3 страниц
все комбинации из 3-х элементов: алгоритм поиска
    #39383142
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имеется последовательность чисел, из последовательности нужно выбрать все возможные комбинации из 3х элементов

существует ли более эффективное решение, чем O(n^3) ?

O(n^3) решение

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
def get_triplets(sqc):
    """ Sequence sqc is a char string: sqc = str(12345) """
    l = len(sqc)
    triplets = []
    for i in range(l-2):
        for j in range(i+1, l-1):
            for k in range(j+1, l):
                triplet = (sqc[i],sqc[j],sqc[k])
                triplets.append(triplet)
    return triplets
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383167
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут нет поиска. Результирующая таблица будет n^3 строк.
Разве что как-то append() оптимизировать, питон не знаю, в других ЯП тормозит выделение памяти, поэтому по хорошему надо сразу создать массив нужного размера, затем заполнять.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383177
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
спасибо, да ты прав по n^3.
попробую поэкспериментировать с выделением памяти
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383334
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

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

Возможно что в предлагаемой мной реализации код станет красивее и необходимость в формировании толстых
Строк отпадает.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383633
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

основная проблема в том, что алгоритм O(n^3) в задаче не прокатывает, и решение через триплеты не работает :(
(я запустила тесты с пустым циклом, и они отвалились по тайм ауту)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383666
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение существует если вы просто неверно описали нам постановку.

Возможно речь идет о перестановках? Или permutations?

https://ru.wikipedia.org/wiki/Перестановка
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383678
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я решила задачу, используя триплет-комбинации O(n^3), но существует лучшее решение O(n)
задача


рабочий брутфорс (чтобы было понятно, что есть правильно по условию)
Код: python
1.
2.
3.
4.
5.
6.
7.
def test_num_of_subsequences(s):    
    l = len(s)
    cnt = 0
    for i in range(1, l+1):
        c = sum(1 for item in combinations(s, i) if  int("".join(item)) % 8 == 0) 
        cnt = cnt + c
    return cnt % (pow(10,9)+7)

...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383781
Фотография S.G.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab задача



автор404

We could not find the page you were looking for, so we found something to make you laugh to make up for it.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383809
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я тоже вижу 404
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39383895
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabимеется последовательность чисел, из последовательности нужно выбрать все возможные комбинации из 3х элементов

существует ли более эффективное решение, чем O(n^3) ?

O(n^3) решение

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
def get_triplets(sqc):
    """ Sequence sqc is a char string: sqc = str(12345) """
    l = len(sqc)
    triplets = []
    for i in range(l-2):
        for j in range(i+1, l-1):
            for k in range(j+1, l):
                triplet = (sqc[i],sqc[j],sqc[k])
                triplets.append(triplet)
    return triplets


такое впечатление что условие задачи неполное. Это стало бы ЗАДАЧЕЙ если бы нужно было, например, выбрать уникальные комбинации или подсчитать их.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384077
просто я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384207
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.
раньше можно было смотреть задачи без регистрации =)
условие задачиGiven an n-digit positive integer, count and print the number of subsequences formed by concatenating the given number's digits that are divisible by 8. As the result can be large, print the result modulo 10^9 + 7

Ограничение: 1 <= n <= 2*10^5

2.
есть проблемы с условием, поэтому я выложила брутфорс, который делает, то что требуется по тестам и по условию
3.
у меня было решение через триплеты сложностью O(n^3), оно не сработало и улучшить его не получится. (о чем DimaT ответил в самом первом посте. )
4.
сложность проходного решения должна быть O(n). O(n*log(n)) - отваливается по тайм-ауту
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384266
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не надо все 2*10^5 разрядов перебирать, 8*10^15 если даже по миллиарду в секунду - 3 месяца перебора :)

Цифр всего 10. В худшем случае, если каждая трижды встречается будет всего 1000 комбинаций.
Выкидываем то что не делится на 8, остается 125.

Дальше обработка каждой комбинации: убираем эти 3 числа и считаем скольки способами можно перетасовать оставшиеся, комбинаторику вспоминай, тут главное учесть повторы, т.е. например из 123 получается 6 комбинаций, а из 112 только 3 (112, 121, 211).
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384293
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

спасибо, буду пробовать

последовательности которые получаются по условию задачи из 112:
[1, 1, 2, 11, 12, 12, 112]

Код для получения последовательностей
Код: python
1.
2.
3.
4.
5.
6.
def all_subsequences(s):    
    l = len(s)
    subs = []
    for i in range(1, l+1):        
        subs.extend([int("".join(item)) for item in combinations(s, i)])
    return subs

...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384310
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabпоследовательности которые получаются по условию задачи из 112:
[1, 1, 2, 11, 12, 12, 112]
С английским у меня не очень, если я правильно это понял
subsequences formed by concatenating the given number's digits
то из 3-хзначного числа могут только 3-хзначные получаться
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384321
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНе надо все 2*10^5 разрядов перебирать, 8*10^15 если даже по миллиарду в секунду - 3 месяца перебора :)

Цифр всего 10. В худшем случае, если каждая трижды встречается будет всего 1000 комбинаций.
Выкидываем то что не делится на 8, остается 125.

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

Не совсем понял про худший случай (трижды встречается), поясните, пожалуйста.

Мне кажется, что условие задачи достаточно запутанно:
count and print the number of subsequences formed by concatenating the given number's digits that are divisible by 8
Тут либо не хватает разъяснений, либо запятых. Потому что непонятно, что должно делиться на 8: составленные числа или цифры из n. А также, как применяется subsequences.
Судя по примеру #0 можно додумать, что имеется ввиду, что мы формируем комбинации не переставляя цифры из n, т.е. если n = 123456789, то 987654321 составить нельзя .
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384329
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabDima T,

спасибо, буду пробовать

последовательности которые получаются по условию задачи из 112:
[1, 1, 2, 11, 12, 12, 112]

Код для получения последовательностей
Код: python
1.
2.
3.
4.
5.
6.
def all_subsequences(s):    
    l = len(s)
    subs = []
    for i in range(1, l+1):        
        subs.extend([int("".join(item)) for item in combinations(s, i)])
    return subs



Как мне кажется, тут перебор нужен умный, например, числа с нечетной цифрой в конце однозначно не будут делится на 8. И я бы строил решение с конца числа n, т.е. находил четное число, а дальше находил бы все комбинации, которые делятся на 8.
Например,

n=59649301

1. 1 - нечетное, пропускаем
2. 0 - четное, формируем все числа, которые делятся на 8
2.1. 2 цифры:
2.1.1. 30 не делится на 8
2.1.2. 90 не делится на 8
2.1.3. 40 делится на 8
...
2.2. 3 цифры
2.2.1. 930 не делится на 8
и т.д.
Решение влоб. Дальше надо оптмизировать.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384331
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пример:

пусть число n = 9680

нам нужно получить все последовательности дающие остаток 0 при делении на 8

1) Все возможные последовательности
[9, 6, 8, 0, 96, 98, 90, 68, 60, 80, 968, 960, 980, 680, 9680]

2) Последовательности, удовлетворящие условию задачи
[8, 0, 96, 80, 968, 960, 680, 9680]

3) Ответ: 8
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384337
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ermak.nn,

число делится на 8 если его последние три разряда делятся на 8. т.е. надо составить все возможные комбинации из 3-х цифр. Например 888 моно составить только если 8-ка повторяется 3 и более раз в исходном.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384340
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabпример:

пусть число n = 9680
ermak.nnНапример,

n=59649301
Вы условия внимательно читали?
Given an n-digit positive integer ... Ограничение: 1 <= n <= 2*10^5
2*10^5 это не максимум 200000, а 10^200000, т.е. 200000 разрядов.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384341
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Спасибо, не знал и забыл я загуглить.

Тогда вы верно все написали. Только там не комбинации надо искать, ибо порядок исходный надо сохранять, как я понял.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384345
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Условие то я правильно прочитал, перепутал в посте. Не n, а вторая строка, которая есть последовательность цифр.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384354
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

все правильно говоришь, n - это число разрядов.
если мой пример переписать в точности по требованиям HR:

Input:
4
9680

Output:
8
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384417
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabпример:

пусть число n = 9680

нам нужно получить все последовательности дающие остаток 0 при делении на 8

1) Все возможные последовательности
[9, 6, 8, 0, 96, 98, 90, 68, 60, 80, 968, 960, 980, 680, 9680]

2) Последовательности, удовлетворящие условию задачи
[8, 0, 96, 80, 968, 960, 680, 9680]

3) Ответ: 8
Еще есть [896, 8096, 8960, 9608] т.е. ответ 12.

У меня получилось 6 [896, 968, 8096, 8960, 9608, 9680]
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384474
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabсуществует ли более эффективное решение, чем O(n^3) ?
Не стоит путать O(n) и O(n^3)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384476
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarermini.weblabсуществует ли более эффективное решение, чем O(n^3) ?
Не стоит путать O(n) и O(n^3)
Виноват, сам затупил и неправильно понял изначальный пост.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384490
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

как сказал ермак, порядок чисел в последовательностях должен быть сохранен,
т.е. если дано число 968, то последовательность из 3х чисел только одна - 968;
далее последовательности из 2х чисел: (96, 98, 68)
ну и т.д. (порядок важен!)

мой пример сделан по условиям, действующим на HR
(я бьюсь над задачей уже 2 дня, так что мне можно доверять)

бруты на питоне можно посмотреть здесь (для тестов)
Код: 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.
def test_num_of_subsequences(n):    
    #ф-я возвращает количество последовательностей, к-рые удовлетворяют условиям задачи
    s = str(n)
    l = len(s)
    cnt = 0
    for i in range(1, l+1):
        c = sum(1 for item in combinations(s, i) if  int("".join(item)) % 8 == 0) 
        cnt = cnt + c
    return cnt % (pow(10,9)+7)

def all_subsequences(s):  
   #функция возвращает все возможные числовые последовательности по задаче
    l = len(s)
    subs = []
    for i in range(1, l+1):        
        subs.extend([int("".join(item)) for item in combinations(s, i)])
    return subs

def good_subsequences(s):    
    #функция возвращает все последовательности, к-рые удовлетворяют условиям задачи
    l = len(s)
    subs = []
    for i in range(1, l+1):        
        subs.extend([int("".join(item)) for item in combinations(s, i) if int("".join(item))%8==0])
    return subs

...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384493
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabкак сказал ермак, порядок чисел в последовательностях должен быть сохранен,
т.е. если дано число 968, то последовательность из 3х чисел только одна - 968;
далее последовательности из 2х чисел: (96, 98, 68)
ну и т.д. (порядок важен!)
И где это в условиях указано?
УсловияGiven an n-digit positive integer, count and print the number of subsequences formed by concatenating the given number's digits that are divisible by 8. As the result can be large, print the result modulo 10^9 + 7

Ограничение: 1 <= n <= 2*10^5
Если эти условия неполные, то зачем вообще надо было сюда их писать? Не понимаю.

Я уже написал что перебор за 3 месяца справится.
С остальным сами с ермаком разбирайтесь. Для ускорения курите комбинаторику.

Удачи. У меня свои головоломки есть.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384511
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

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

кроме того, я думаю, что смогу улучшиться, применив то, что ты написал здесь 20103342
т.е не генерировать все тройки, а работать только с теми к-рые делятся на 8

в общем спасибо =)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384889
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
удалось улучшится, но все равно, тест O(n) падает...

задача:
пусть имеется число num, состоящее из чисел n. (пример: n=4, num=9680)
требуется подсчитать все комбинации дающие 0 в остатке при делении на 8.

пример:
пусть число num = 9680
нам нужно получить все последовательности дающие остаток 0 при делении на 8

1) Все возможные последовательности
[9, 6, 8, 0, 96, 98, 90, 68, 60, 80, 968, 960, 980, 680, 9680]

2) Последовательности, удовлетворящие условию задачи
[8, 0, 96, 80, 968, 960, 680, 9680]

3) Ответ: 8

решение:
будем рассматривать взносы следующих элементов последовательности:
1) числа 0 и 8: вес 1
2) пары, делящиеся на 8: вес 1
3) тройки, делящиеся на 8: вес 2^idx, idx - позиция первого элемента тройки в последовательности
(пример. числовая последовательность: 9680; тройка: 680; вес тройки 680: 2^1)

Python code:

Код: 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.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
# четные пары: тройка начинается четным числом
TRIPLE_ZERO = ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'] 
# нечетные пары: тройка начинается нечетным числом
TRIPLE_ONE = ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92']

def get_dictionary(sqc):
    """
        начальная последовательность будет записана в словарь
    """
    d = {'0':[], '1':[], '2':[], '3':[], '4':[], '5':[], '6':[], '7':[], '8':[], '9':[]}
    for i in range(len(sqc)):
        d[sqc[i]].append(i)
    return d

def get_binary_dictionary(sqc):
    """
        бинарный словарь хранит позиции четных и нечетных числел последовательности
    """
    d= {0:[], 1:[]}
    for i in range(len(sqc)):
        d[int(sqc[i])%2].append(i)
    return d

def get_list(sqc, data_dict, lookup):
    """
        используется для генерации списка типа (нач_позиция, частота) для четных и нечетных чисел
    """
    data = data_dict
    d = []
    for item in lookup:
        n1 = item[0]
        n2 = item[1]
        if len(data[n1])>0 and len(data[n2])>0:

            l1 = len(data[n1])
            l2 = len(data[n2])
            for i in range(l1):
                for j in range(l2):
                    if data[n1][i]<data[n2][j]:
                        m = len(data[n2][j:])
                        d.append( (data[n1][i],m) )
                        break
    d.sort()
    return d

def num_of_subsequences(sqc):
    # main sequence value dictionary
    main_dict = get_dictionary(sqc)
    # compute singles
    singles = len(main_dict['0']) + len(main_dict['8'])
    # compute doubles
    doubles_zero = get_list(sqc, main_dict, TRIPLE_ZERO)
    #print(doubles_zero)
    doubles = sum(item[1] for item in doubles_zero)
    # coumpute triples
    triples = 0    
    binary_dict = get_binary_dictionary(sqc)  
    doubles_one = get_list(sqc, main_dict, TRIPLE_ONE) 
    for idx in binary_dict[0]:
        for item in doubles_zero:
            if idx < item[0]:
                s0 = sum(el[1] for el in doubles_zero if item[0]<=el[0])
                triples = triples + pow(2, idx) * s0
                break

    for idx in binary_dict[1]:
        for item in doubles_one:
            if idx < item[0]:
                s0 = sum(el[1] for el in doubles_one if item[0]<=el[0])
                triples = triples + pow(2, idx) * s0
                break    

    return (singles + doubles + triples)%(pow(10,9)+7)


n = int(input().strip())
number = input().strip()
print(num_of_subsequences(number))



пояснение по четным-нечетным парам:

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TRIPLE_DICT = {'0': ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'], 
               '1': ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92'], 
               '2': ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'], 
               '3': ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92'], 
               '4': ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'], 
               '5': ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92'], 
               '6': ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'], 
               '7': ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92'], 
               '8': ['00', '08', '16', '24', '32', '40', '48', '56', '64', '72', '80', '88', '96'], 
               '9': ['04', '12', '20', '28', '36', '44', '52', '60', '68', '76', '84', '92']}


...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384978
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

если правильно понял,
перебор сочетаний с доп. условием делимости полученного числа;
и то, и другое реализуется элементарно.

Единственное тонкое место - условие делимости должно относиться не в целом к числу,
а должно быть расписано для каждого знакоместа, чтобы его можно было использовать
на этапе выбора очередного сочетания.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384981
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

Или еще проще, в цикле от 0 до 124 (по возможным значениям 3х последних цифр) подсчитать количество сочетаний с произвольными начальными цифрами (умножить на 2^K)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39384986
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr SharahovAleksandr Sharahov,

Или еще проще, в цикле от 0 до 124 (по возможным значениям 3х последних цифр) подсчитать количество сочетаний с произвольными начальными цифрами (умножить на 2^K)я так и сделала, но возникли проблемы с технической реализацией (код работает не так быстро, как нужно)
из решения mini.weblab3) тройки, делящиеся на 8: вес 2^idx, idx - позиция первого элемента тройки в последовательности
(пример. числовая последовательность: 9680; тройка: 680; вес тройки 680: 2^1)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39385123
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
другими словами, на данном этапе получен код решения сложности O(n^2),
а нужен код решения сложность O(n)

Aleksandr Sharahovв цикле от 0 до 124 (по возможным значениям 3х последних цифр) подсчитать количество сочетаний с произвольными начальными цифрами (умножить на 2^K)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39385204
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabдругими словами, на данном этапе получен код решения сложности O(n^2),
а нужен код решения сложность O(n)

Aleksandr Sharahovв цикле от 0 до 124 (по возможным значениям 3х последних цифр) подсчитать количество сочетаний с произвольными начальными цифрами (умножить на 2^K)

Идем справа налево.
В процессе работы ведем списки (таблицы) единиц, двоек и троек.
Очередная цифра либо меняет списки (не более 125 раз), либо не создает ничего нового в этих списках (все остальные разы).
Для каждой цифры наращиваем счетчик на (2^k mod x) по mod x.
O(N).
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39385495
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

если у вас будет время, опишите пожалуйста, реализацию вашего алгоритма на примере.
(подойдет так же псевдокод или код, на любом языке программирования)

спасибо заранее
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39385747
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

Все проще, но 2 прохода.

Первый справа налево. Задача - определить начала всех 125 уникальных троек с делимостью на 8, а также наличие двоек и единиц.
Например, в строке 9680 тройки 968 и 960 начинаются в первой позиции, тройка 680 - во второй, имеются 2 двойки (96, 80) и 2 единицы (8, 0). Очевидно, вклад двоек и единиц в общую сумму просто равен их общему количеству (4).
Сортируем позиции начала троек по возрастанию (сами тройки нам уже не важны): 1,1,2.

Второй проход слева направо. Считаем количество подпоследовательностей, включая пустую, до начала каждой тройки и складываем. У нас имеется 1 пустая подпоследовательность до позиции 1, она же - еще раз до позиции 1, и две подпоследовательности (пустая и 9) до позиции 2. Итого +4 к общей сумме.

Как считать количество подпоследовательностей (включая пустую) - известно (разумеется, надо адаптировать):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
function count(const s: string): integer;
var
  sum: array['0'..'9'] of integer; 
  old, i: integer;
  ch: char;
begin;
//общее количество = одна пустая
  Result:=1; 
//количества подпоследовательностей с концом на '0'..'9' вначале 0
  for ch:='0' to '9' do sum[ch]:=0;  
//крутим цикл по всем цифрам строки
  for i:=1 to Length(s) do begin;
//текущая цифра
    ch:=s[i];
//столько кончалось на ch
    old:=sum[ch];
//теперь столько кончается на ch из общего количества
    sum[ch]:=Result; 
//а общее количество удвоилось, т.к. ch можем добавить в конец, а можем и нет
//но при этом дважды посчитали old
    Result:=Result+Result-old; 
    end;
  end;
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39385866
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшое пояснение.
Может показаться, что учтя только вклад только одного (последнего) вхождения каждой из 125 троек в качестве 125 слагаемых, мы что-то забыли и надо было как-то учесть предыдущие вхождения каждой тройки. Это не так. Требование неповторяемости подпоследовательностей сильно упрощает нашу задачу. В самом деле, рассмотрим произвольную подпоследовательность xyz504, которую сформировало первое слева вхождение тройки 504. Последнее слева (или первое справа, как у нас) вхождение тройки 504 также может сформировать подпоследовательность xyz504, xyz лежит левее. Получается, что мы автоматически учли и ее.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386074
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,
спасибо Александр.
у меня основная проблема с учетом всех двоек(троек) в последовательности, именно эта часть и отнимает O(n^2) времени.
(тройки в результате сводятся к двойкам)
дальше, когда информация (двойка, позиция) собрана, подсчитать комбинации несложно
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386076
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

там нигде нет O(N^2)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386108
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,
у вас, может быть и нет, а у меня-то есть :)
в общем, я еще до конца не разобралась, сегодня вечером попробую еще раз
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386192
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

особо не отлаживал, но для 9680 результат верный
[delphi]
function CountSeq8(const s: string): integer;
const
Prim = 1000 * 1000 * 1000 + 7;
var
Found1, Refresh2, Refresh3: array[0..9] of boolean;
Found2: array[0..99] of boolean;
Found3: array[0..999] of integer;
MinPos3, Sum: array[0..9] of integer;
i, j, k, m, Count, Old: integer;
begin;
//Шаг1 - просмотр справа налево, подсчет единиц, двоек, определение начал троек.
for i:=0 to 9 do begin;
Found1[i]:=false;
Refresh2[i]:=false;
Refresh3[i]:=false;
MinPos3[i]:=MaxInt;
end;
for i:=0 to 99 do Found2[i]:=false;
for i:=0 to 999 do Found3[i]:=MaxInt;
for i:=Length(s) downto 1 do begin;
j:=Ord(s[i])-Ord('0');
if Refresh3[j] then begin;
Refresh3[j]:=false;
m:=j*100;
k:=m+96-(j and 1)*4;
repeat;
if (Found3[k]=MaxInt) and Found2[k-m] then begin;
Found3[k]:=i;
MinPos3[j]:=i;
end;
k:=k-8;
until k<m;
end;
if Refresh2[j] then begin;
Refresh2[j]:=false;
m:=j*10;
for k:=0 to 9 do if Found1[k] then Found2[m+k]:=true;
end;
if not Found1[j] then begin;
Found1[j]:=true;
for k:=0 to 9 do begin;
Refresh2[k]:=true;
Refresh3[k]:=true;
end;
end;
end;
Result:=0;
for i:=0 to 9 do if (i and 7=0) and Found1[i] then inc(Result);
for i:=0 to 99 do if (i and 7=0) and Found2[i] then inc(Result);

//Шаг2 - просмотр слева направо, суммирование количества подпоследовательностей с концами на тройках.
Count:=1;
for i:=0 to 9 do Sum[i]:=0;
for i:=1 to Length(s) do begin;
j:=Ord(s[i])-Ord('0');
if i=MinPos3[j] then begin;
MinPos3[j]:=MaxInt;
m:=j*100;
k:=m+96-(j and 1)*4;
repeat;
if Found3[k]=i then begin;
Found3[k]:=MaxInt;
Result:=Result+Count; if Result>=Prim then Result:=Result-Prim;
end
else if MinPos3[j]>Found3[k] then MinPos3[j]:=Found3[k];
k:=k-8;
until k<m;
end;
Old:=Sum[j];
Sum[j]:=Count;
Count:=Count+Count-Old; if Count>=Prim then Count:=Count-Prim;
end;
end;
[/delphi]
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386195
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov, улетело форматирование
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386372
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

спасибо!
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39386486
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исправлена неточность с рефрешем поиска троек, немного ускорено (хотя там еще есть где ускорить).
Кроме 9680 правильно обрабатывает CountSeq8('968046122') = 12 (0 8 64 80 96 912 904 984 680 960 968 9680)

Код: pascal
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.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
function CountSeq8(const s: string): integer;
const
  Prim = 1000 * 1000 * 1000 + 7;
var
  Found1, Refresh2, Refresh3: array[0..9] of boolean;
  Found2: array[0..99] of boolean;
  Found3: array[0..999] of integer;
  MinPos3, Sum: array[0..9] of integer;
  i, j, k, m, h, Count, Old: integer;
begin;
  //Шаг1 - просмотр справа налево, подсчет единиц, двоек, определение начал троек.
  for i:=0 to 9 do begin;
    Found1[i]:=false;
    Refresh2[i]:=false;
    Refresh3[i]:=false;
    MinPos3[i]:=MaxInt;
    end;
  for i:=0 to 99 do Found2[i]:=false;
  for i:=0 to 999 do Found3[i]:=MaxInt;
  for i:=Length(s) downto 1 do begin;
    j:=Ord(s[i])-Ord('0');
    if Refresh3[j] then begin;
      Refresh3[j]:=false;
      m:=j*100;
      k:=m+96-(j and 1)*4;
      repeat;
        if (Found3[k]=MaxInt) and Found2[k-m] then begin;
          Found3[k]:=i;
          MinPos3[j]:=i;
          end;
        k:=k-8;
        until k<m;
      end;
    if Refresh2[j] then begin;
      Refresh2[j]:=false;
      m:=j*10; k:=m+8-(j and 1)*2;
      repeat;
        if Found1[k-m] and not Found2[k] then begin;
          Found2[k]:=true;
          h:=k shr 2 and 1 + 8;
          repeat;
            if Found3[100*h+k]=MaxInt then Refresh3[h]:=true;
            h:=h-2;
            until h<0;
          end;
        k:=k-4;
        until k<m;
      end;
    Found1[j]:=true;
    if j and 1=0 then for k:=0 to 9 do if not Found2[10*k+j] then Refresh2[k]:=true;
    end;
  Result:=0;
  for i:=0 to 9 do if (i and 7=0) and Found1[i] then inc(Result);
  for i:=0 to 99 do if (i and 7=0) and Found2[i] then inc(Result);

  //Шаг2 - просмотр слева направо, суммирование количества подпоследовательностей с концами на тройках.
  Count:=1;
  for i:=0 to 9 do Sum[i]:=0;
  for i:=1 to Length(s) do begin;
    j:=Ord(s[i])-Ord('0');
    if i=MinPos3[j] then begin;
      MinPos3[j]:=MaxInt;
      m:=j*100;
      k:=m+96-(j and 1)*4;
      repeat;
        if Found3[k]=i then begin;
          Found3[k]:=MaxInt;
          Result:=Result+Count; if Result>=Prim then Result:=Result-Prim;
          end
        else if MinPos3[j]>Found3[k] then MinPos3[j]:=Found3[k];
        k:=k-8;
        until k<m;
      end;
    Old:=Sum[j];
    Sum[j]:=Count;
    Count:=Count+Count-Old; if Count>=Prim then Count:=Count-Prim;
    end;
  end;
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387004
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В предыдущей версии есть неточность. Иногда может быть получен отрицательный результат из-за того что при суммировании-вычитании по модулю учтено переполнение только в положительную сторону. Правильный код должен быть таким:
Код: pascal
1.
2.
3.
    Count:=Count+Count-Old;
    if Count>=Prim then Count:=Count-Prim
    else if Count<0 then Count:=Count+Prim;




Здесь ускоренная примерно в 2 с лишним раза версия, почти нечитаемая.
Интенсивно используется работа с битами. Нервным и беременным лучше не смотреть.
Код: pascal
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.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
function CountSeq82(const s: string): integer;
const
  Prim = 1000 * 1000 * 1000 + 7;
var
  i, j, k, m, h, t: integer;
  Found2, Empty2, Refresh2, Count, Old, Total3: integer;
  Pos3: array[0..124] of integer;
  Mask1, Mask2, MinPos3, Sum: array[0..9] of integer;
  Found1, Refresh3: array[0..9] of boolean;
label
  Done1, Done2;
begin;
  //Шаг1 - просмотр справа налево, подсчет единиц, двоек, определение начал троек.
  Total3:=0;
  Refresh2:=0; Found2:=0; Empty2:=Found2 xor $01FFFFFF;
  for i:=0 to High(Pos3) do Pos3[i]:=MaxInt;
  for i:=0 to 9 do begin;
    MinPos3[i]:=MaxInt;
    Refresh3[i]:=false;
    Found1[i]:=false;
    Mask1[i]:=0;
    Mask2[i]:=0;
    end;
  for i:=0 to 24 do begin; //24=96 div 4
    j:=i*4;
    k:=j div 10;
    m:=j - k*10;
    j:=1 shl i;
    Mask2[k]:=Mask2[k] or j;
    Mask1[m]:=Mask1[m] or j;
    end;

  for i:=Length(s) downto 1 do begin;
    j:=Ord(s[i])-Ord('0');
    if Refresh3[j] then begin;
      k:=24 - (j and 1);
      m:=j shr 1 * 25 + k;
      k:=1 shl k;
      Refresh3[j]:=false;
      repeat;
        if (Pos3[m]=MaxInt) and (Found2 and k<>0) then begin;
          Pos3[m]:=i;
          MinPos3[j]:=i;
          inc(Total3); if Total3=125 then goto Done1;
          end;
        k:=k shr 2;
        m:=m-2;
        until k=0;
      end;
    t:=Mask2[j] and Refresh2;
    if t<>0 then begin;
      m:=8-(j and 1)*2;
      k:=1 shl ((j*10+m) shr 2);
      Refresh2:=t xor Refresh2;
      repeat;
        if t and k<>0 then begin;
          h:=(j*10+m) shr 2 and 1 + 8;
          Found2:=Found2 xor k;
          repeat;
            Refresh3[h]:=true;
            h:=h-2;
            until h<0;
          end;
        k:=k shr 1;
        m:=m-4;
        until m<0;
      Empty2:=Found2 xor $01FFFFFF;
      end;
    Found1[j]:=true;
    if j and 1=0 then Refresh2:=Mask1[j] and Empty2 or Refresh2;
    end;
Done1:
  Result:=0;
  for i:=0 to 9 do if (i and 7=0) and Found1[i] then inc(Result);
  for i:=0 to 24 do if (i and 1=0) and (Found2 shr i and 1<>0) then inc(Result);

  //Шаг2 - просмотр слева направо, суммирование количества подпоследовательностей с концами на тройках.
  Count:=1;
  for i:=0 to 9 do Sum[i]:=0;
  for i:=1 to Length(s) do begin;
    j:=Ord(s[i])-Ord('0');
    if i=MinPos3[j] then begin;
      MinPos3[j]:=MaxInt;
      m:=j shr 1 * 25;
      k:=24 - (j and 1) + m;
      repeat;
        if Pos3[k]=i then begin;
          Pos3[k]:=MaxInt;
          Result:=Result+Count; if Result>=Prim then Result:=Result-Prim;
          //dec(Total3); if Total3=0 then goto Done2;
          end
        else if MinPos3[j]>Pos3[k] then MinPos3[j]:=Pos3[k];
        k:=k - 2;
        until k<m;
      end;
    Old:=Sum[j];
    Sum[j]:=Count;
    Count:=Count+Count-Old;
    if Count>=Prim then Count:=Count-Prim
    else if Count<0 then Count:=Count+Prim;
    end;
Done2:
  end;
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387199
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

у вас точно решить и не получится, потому что вы не знаете всех условий :)
точное условие и тесты здесь (в том числе и на производительность здесь)
https://www.hackerrank.com/contests/w28/challenges/lucky-number-eight/copy-from/1300178868
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387206
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и еще,
по-моему, в задаче можно обойтись двойками + использовать четность-нечетность первых цифр
(пробую реализовать)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387209
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabAleksandr Sharahov,

у вас точно решить и не получится, потому что вы не знаете всех условий :)
точное условие и тесты здесь (в том числе и на производительность здесь)
https://www.hackerrank.com/contests/w28/challenges/lucky-number-eight/copy-from/1300178868

Tо, что привел и есть точное решение )
И производительность, думаю неплохая: - 1.3ms на случайных последовательностях максимальной длины.
А рангами не заморачиваюсь )
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387212
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поправочка:
1.3ms - специально подобранный худший случай,
0.6ms - случайные данные.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387213
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

а еще там в Editorial должны были выложить решение (но я пока его не смотрела)
=)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387222
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabа еще там в Editorial должны были выложить решение (но я пока его не смотрела)
=)

Хорошо бы его здесь потом увидеть
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387251
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все-таки решил попробовать.
Завалил первый же тест на строке 968.
Странно, на моем компе последняя версия дает 3 (правильный ответ), а у них она же дает 1.
Подозреваю, что иначе компилируются логические выражения.
В общем, попробовал, и ладно.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387258
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще не понимаю, почему для 00000 правильный ответ не 5, а 31.
Похоже, мы решаем разные задачи.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387283
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

просто задача была некорректно сформулирована изначально и по ходу соревнования исправлялась
для 00000 ответ действительно 31:
['0', '0', '0', '0', '0', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '000', '000', '000', '000', '000', '000', '000', '000', '000', '000', '0000', '0000', '0000', '0000', '0000', '00000']

генератор искомых комбинаций:
Код: python
1.
2.
3.
4.
5.
6.
7.
def good_subsequences(s):    
    l = len(s)
    subs = []
    for i in range(1, l+1):        
        subs.extend(["".join(item) for item in combinations(s, i) if int("".join(item))%8==0])
    subs.sort()
    return subs


Питон строит комбинации по индексам списка (не по значениям, а по индексам). В задаче требуется то же самое.
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387285
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr Sharahov,

ответ для 968 на самом деле 3 и есть: (8, 96, 968)
...
Рейтинг: 0 / 0
все комбинации из 3-х элементов: алгоритм поиска
    #39387360
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblabAleksandr Sharahov,

ответ для 968 на самом деле 3 и есть: (8, 96, 968)

1. Это-то понятно. Непонятно, почему один и тот же алгоритм (с заданными начальными значениями переменных) работает по-разному у них и у меня.

2. Да, они решают другую задачу. У них если хоть одна использованная цифра взята с другой позиции, то подпоследовательности считаются различными. Т.е. сравниваются не строки, а вектора использованных позиций.
...
Рейтинг: 0 / 0
57 сообщений из 57, показаны все 3 страниц
Форумы / Программирование [игнор отключен] [закрыт для гостей] / все комбинации из 3-х элементов: алгоритм поиска
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]