О проблеме ... Он никогда не спрашивал об оптимальном решении, и эти типы вопросов не хотят этого. Вам нужно написать алгоритм общего назначения для решения этой проблемы, и поиск грубой силы для поиска наилучшего решения невозможен для строк, длина которых может быть мегабайт. Также я заметил поздно, что гарантировано будет такое же количество 0 и 1, но я думаю, что более интересно работать с общим случаем, где могут быть разные числа 0 и 1. На самом деле не гарантируется решение в каждом случае, если длина входной строки меньше 7, даже если у вас есть 2 0s и 2 1s.
Размер 3: Только одна цифра так сортируется по определению (UU0 UU1 0UU 1UU)
Размер 4: Ни в коем случае, чтобы изменить порядок. Нет никаких ходов, если UU находится посередине и только обменивается обеими цифрами, если он находится на конце (1UU0 нет ходов, UU10-> 10UU-> UU10 и т. Д.)
Размер 5: UU в середине может только перемещайтесь в дальний конец и не меняйте порядок 0s и 1s (1UU10-> 110UU).UU на конце может перемещаться в середину и не менять порядок, а только возвращаться к тому же концу, поэтому для него нет необходимости (UU110-> 11UU0-> UU110). Единственный способ изменить цифры - это то, что UU находится на конце и поменяется с противоположным концом. (UUABC-> BCAUU или ABCUU-> UUCAB). Это означает, что если UU находится в положениях 0 или 2, он может решить, если 0 находится посередине (UU101-> 011UU или UU100-> 001UU), и если UU находится в положениях 1 или 3, он может решить, если 1 находится посередине (010UU-> UU001 или 110UU-> UU011). Все остальное уже разрешено или неразрешимо. Если нам нужно будет справиться с этим делом, я бы сказал, что это жесткий код. Если отсортировано, верните результат (без ходов). Если UU находится где-то посередине, переместите его в конец. Переходите от конца к другому концу, и это единственный возможный обмен, теперь он отсортирован или нет.
Размер 6: Теперь мы получаем такую позицию, в которой у нас может быть строка, указанная в соответствии с правилами, в которых мы можем делать ходы, но где не может быть никакого решения. Это проблема с любым алгоритмом, потому что я думаю, что условие любого решения должно состоять в том, чтобы оно сообщило вам, если оно не может быть разрешено. Например, 0010, 0100, 1000, 1011, 1100, 1101 и 1110 могут быть решены независимо от того, где размещается UU, а наихудшие - для 4-х шагов. 0101 и 1010 могут быть решены только в том случае, если UU находится в нечетном положении. 0110 и 1001 могут быть решены только в том случае, если UU находится в ровном положении (концевое или среднее).
Я думаю, что лучший способ будет чем-то вроде следующего, но я еще не написал его. Во-первых, убедитесь, что вы поместили «1» в конец списка. Если конец в настоящий момент 0, переместите UU до конца, а затем переместите его в последнюю позицию «1» - 1. После этого вы постоянно переместите UU на первый «1», а затем на первый «0» после нового UU. Это переместит все 0s в начало списка. Я видел подобный ответ в обратном порядке, но он не принимал во внимание конечного персонажа с обоих концов. Это может привести к проблемам с небольшими значениями (т. Е. 001UU01, не может перейти к первому 1, перейти к концу 00101UU позволяет нам двигаться, чтобы начать, но оставляет 0 в конце 00UU110).
Я предполагаю, что вы можете жестко закодировать специальные случаи. Я думаю, что может быть лучший алгоритм. Например, вы можете использовать первые два символа как временную переменную swap. Вы бы поставили UU, а затем сделали комбинации операций над другими, чтобы оставить UY в начале. Например, UUABCDE может заменить AB на CD или DE или BC с DE (BCAUUDE-> BCADEUU-> UUADEBC).
Еще одна возможная вещь - обработать символы, поскольку два блока из двух базовых 3 бит 0101UU0101 будет отображаться как 11C11 или 3593. Возможно, что-то вроде комбинации жестко закодированных свопов. Например, если вы когда-либо видели 11UU, переместите UU слева 2. Если вы когда-нибудь увидите UU00, переместите UU вправо два. Если вы видите UU100 или UU101, переместите UU справа 2, чтобы получить 001UU или 011UU.
Может быть другая возможность будет некоторый алгоритм перемещения 0s влево от центра и 1s справа от центра (если дано, что существует такое же количество 0s и 1s.
Может быть, было бы лучше работать на структура, содержащая только 0s и 1s с позицией для UU.
Возможно, посмотрите на полученное условие лучше, позволяя UU находиться где угодно в строке, эти условия ДОЛЖНЫ быть выполнены: Нет 0 с после длины/2 № 1s before (Длина/2-1)
Возможно, ere являются более общими правилами, так как это действительно хорошо, чтобы поменять UU на 10 в этом случае «10111UU0», потому что «0» после UU теперь, и это позволит вам переместить новый 00 обратно туда, где было 10 (10111UU0-> UU111100 -> 001111UU).
В любом случае, вот код грубой силы в C#. Вход представляет собой строку и пустой словарь.Он заполняет словарь с каждой возможной результирующей строкой в качестве ключей и списка коротких шагов, чтобы попасть в качестве значения:
Вызов:
m_Steps = new Dictionary<string, List<string>>();
DoSort("UU1010011101", new List<string>);
Она включает DoTests(), который вызывает DoSort для каждой возможной строки с указанным числом цифр (не включая UU):
Хорошая проблема. Был ли он загружен онлайн-судье после конкурса? Если да, вы можете ссылаться на него? – IVlad
Нет, ничего не было опубликовано. – KovBal
Хотелось бы отметить, что наиболее интересной частью этой задачи является то, что U count всегда 2, а нули и единицы могут быть, например, 3. Это делает его намного сложнее: '0101UU01' =>' 0UU11001' => '001110UU' =>' 00UU1011' => '00011UU1' (может быть, есть более быстрый способ, но я просто привел пример того, как это тяжело). – bezmax