imho.ws |
![]() |
![]() |
![]() |
# 1 |
Full Member
Регистрация: 20.01.2004
Адрес: Таллинн
Пол: Male
Сообщения: 623
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Нужно составить алгоритм
Есть кроссворд. Любой. На пример как на картинке.
И есть набор чисел, которых в несколько раз больше, чем поместится в кроссворд. На пример: 92365 13846 4356 128 95 1250 3916735 3594 190346 5843 9571 126534 59 21 39468 593823 96986 9348 594756 33466 Нужно составить алгоритм, который заполняет кроссворд числами из списка. Условие: чтобы сумма цифр из всех квадратов в кроссворде получилась максимальная. Конкретно я немогу понять через что представлять сам кроссворд (массив? дерево?). И как проверять какие места свободны, какие частично заняты. И ещё: Квадрат разбит на девять частей. В каждой части вписана буква: T __ S __ E K __ I __ H U __ R __ A Нужен алгоритм, выписывающий все возможные комбинации (слова) из этих букв. Условие: минимум четыре буквы, в каждой комбинации должна быть буква I (середина квадрата), каждая буква может присутствовать только один раз. |
![]() |
![]() |
# 2 |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Под конец рабочего дня уже соображать трудно - но рискну предложить решение по первой части задачи - так как ни каких дополнительных условий не указанно то максимальная сумма кросворда - это сумма всех чисел - минус сумма чисел не вошедших в кроссворд.
![]() И не очень понятно, что имеется ввиду под представлением. Если имеется ввиду хранение результатов - то каждая ячейка описывается положением по горизонтали и по вертикали - то есть, как вариант, для ее хранения можно создать структуру, членами которой является позиция по Х У и собственно значение ячейки. А хранить ее можно или в двумерном массиве - самое простое, но не самое эффективное, или использовать два контейнера с уникальным значением ключа. В качестве ключа использовать соответственно в одном случае Х в другом У. Я бы сделал это так - Код:
typedef multiset<Struct>Cell; typedef map<int,multiset<Struct>::iterator>X; typedef map<int,multiset<Struct>::iterator>Y; ![]() Последний раз редактировалось kot_; 22.11.2004 в 21:38. |
![]() |
![]() |
# 3 | |
Full Member
Регистрация: 20.01.2004
Адрес: Таллинн
Пол: Male
Сообщения: 623
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Цитата:
То есть вписали число 3465, считаем: 3+4+6+5. В кроссворд надо добавлять как слова: если число из трёх цифр, то оно займёт три квадрата. Потом считать сумму всех квадратов. Получившийся алгоритм для заполнения должен работать со словами тоже (может быть при минимальном изменении). Меня больше всего интересует как сделать перересечение линий в кроссворде. Если в одной линии я вписал 2 7 9 4 2 5, предположим цифра 4 попала на пересечение. Тогда нужно както вычислить, что по другой линии одна цифра уже есть. Соответственно туда надо искать число соответствующее условию. |
|
![]() |
![]() |
# 4 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
То есть в первом приближении алгоритм выглядит так: 1. Шаг первый - инициализируешь сетку кроссворда - т.е. заполняешь массивы структурами с установленным значением Х и У и присваеваешь им уникальный идентификатор. 2. Получаешь длину строки которую необходимо заполнить. 3. Находишь число совпадающее с длиной строки. 4. Раскладываешь его на составляющие и получаешь сумму. 5. Проверяешь на соответствие условиям. 6. Помещаешь в ячейки. 7.Повторяешь со 2 до тех пор пока не дойдешь до последней ячейки. ![]() |
|
![]() |
![]() |
# 5 |
Full Member
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557
![]() ![]() ![]() ![]() |
хм... интересная задачка. А ты можешь предложить быстрый алгоритм который будет просто законно заполнять кроссворд?
Kot (Sorrryyyy!) предложил по крайней мере O(n*n) Последний раз редактировалось Drakosha; 24.11.2004 в 00:42. |
![]() |
![]() |
# 6 |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Male - это кто?
![]() Конечно, приведеныый алгоритм может быть оптимизирован, но по сути он все же сводится к О(n*n). Возможно повышение эффективности и свдение задачи к алгоритму поиска в бинарном дереве (блин хочется ![]() ![]()
__________________
![]() Последний раз редактировалось kot_; 23.11.2004 в 20:33. |
![]() |
![]() |
# 7 |
Full Member
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557
![]() ![]() ![]() ![]() |
проблема в том что кроме перебора (оптимизированного по частотам и т.д.), т.е. greedy никаких идей нету. К тому же ето не обеспечивает ОПТИМАЛьНОГО заполнения. Можно подумать о каких нибудь генетических алгоритмах... но как найти оптималный ответ???
|
![]() |
![]() |
# 8 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
__________________
![]() |
|
![]() |
![]() |
# 10 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
Поместить в массив - заканчивается на согласную. Выделить сочетания в которых буквы из первого массива находятся в первой, третьей позиции и четвертой, I во второй. В получившихся сочетаниях последовательно заменить третью позицию буквами из второго массива, потом четвертую. Поместить - заканчиваются на гласную. Полученные сочетания из заканчивается на первом этапе добавить пятой из массива гласных сравнив с первой и второй позицией. И так до конца. То есть предполагается что сочетаний типа TSHKIUAE быть не должно.
__________________
![]() |
|
![]() |
![]() |
# 13 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
__________________
![]() |
|
![]() |
![]() |
# 15 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
- скопировать первые три элемента в слово -записать - скопировать следующие три элемента -пункт 2 -скопировать первый второй и четвертый -пункт два -скопировать первый второй и пятый -пункт два -скопировать первый второй и шестой ... -скопировать первый третий и четвертый и так далее. Потом первый элемент массива копируется во вторую позицию второй в первую. Выполняешь последовательно теже шаги. Затем третий элемент копируется в первую. Опять прогоняешь Когда все элементы массива пройдут первую позицию смещаешь второй на место третьего и опять итерация. То есть выполняешь все шаги до тех пор, пока первый элемент массива не вернется в начало. То же самое используешь для 5 и более буквенных. Но здесь возможны два варианта - с одной строны у тебя уже есть 4-х буквенные слова - можно использовать их - но тогда на этом этапе должна быть добавлена функция проверки на наличие буквы - мне кажется это может усложнить работу с алгоритмом. И по этому, я бы использовал тот же принцип что и для 4-х буквенных но соответственно копировал просто большее колво элементов.
__________________
![]() |
|
![]() |
![]() |
# 16 |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Могу добавить, что имеет смысл не забывать о нумерации с нуля. Это упростит работу с постоянным символом - его позиция в массиве - это количество символов перед ним. Что позволяет избежать кучи if() else - я имею ввиду, что нет нужды проверять в какой позиции находится постоянная буква - нужно просто использовать позицию ее цикла итерации - например если в текущей итерации буква I находится в первой позиции - ее номер 0 - если в во второй и больше - позиция каждой вычисляется следующим образом - для букв перед - (индекс буквы+1)-(индекс постоянной буквы в массиве - количество букв перед) -1. Для букв после (индекс буквы+1)-(индекс постоянной буквы в массиве - количество букв перед).
![]()
__________________
![]() |
![]() |
![]() |
# 18 |
Advanced Member
Регистрация: 09.03.2004
Адрес: толстозадая Москва
Сообщения: 498
![]() ![]() ![]() ![]() |
Маленькое предположение - а не получится разложить или развернуть квадрат в дерево с корнем в I, а потом просто различные обходы делать??? ИМХО если получится, то тогда можно опять же стандартными контейнерами решить, что в разы быстрее тривиального перебора...
Не утверждаю что так получится, но вдруг ![]() ![]() |
![]() |
![]() |
# 19 | |
Junior Member
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67
![]() |
Цитата:
![]()
__________________
![]() |
|
![]() |