Ладьи |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
Ладьи |
nastya_ab |
Сообщение
#1
|
Гость |
Помогите пожалуйста!
Ладьи. Требуется найти такую расстановку 8 ладей на шахматной доске, при которой они не будут угрожать друг другу. Первые три фигуры расставляет пользователь. |
Lapp |
Сообщение
#2
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Введи два множества: для букв и для цифр. Затем выбирай расположение так, чтобы ни буква, ни цифра не была в соответствующем множестве (случайный перебор). Найденные позиции добавляй к множествам.
То есть примерно вот так (опускаю тут ручной ввод позиций первых трех ладей) : for i:=4 to 8 do begin -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
nasta_ab |
Сообщение
#3
|
Гость |
Введи два множества: для букв и для цифр. Затем выбирай расположение так, чтобы ни буква, ни цифра не была в соответствующем множестве (случайный перебор). Найденные позиции добавляй к множествам. То есть примерно вот так (опускаю тут ручной ввод позиций первых трех ладей) : for i:=4 to 8 do begin Спасибо. |
klem4 |
Сообщение
#4
|
Perl. Just code it! Группа: Пользователи Сообщений: 4 100 Пол: Мужской Реальное имя: Андрей Репутация: 44 |
На сомом деле не лучший вариант, и по идее чисто теоретически возможен вариант когда решение никогда не будет найдено, считай фактически зацикливание, маловероятно конечно но всеже ...
Сообщение отредактировано: klem4 - -------------------- perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
|
Michael_Rybak |
Сообщение
#5
|
Michael_Rybak Группа: Пользователи Сообщений: 1 046 Пол: Мужской Реальное имя: Michael_Rybak Репутация: 32 |
А по-моему вариант хороший Вероятность того, что оно зациклится хотя бы на пять секунд, я думаю, меньше вероятности того, что за эти пять секунд вырубится электричество в комп. классе во время проверки А раз просят не какое-то определенное решение, то прикольно, чтоб выдавало рандомное.
|
Lapp |
Сообщение
#6
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
А мне кажется, что klem4 прав. По сути, я ждал этого вопроса. Клем только забыл главный аргумент - масштабируемость. Ведь никто не сказал, что доска не может быть, скажем, 1000х1000 или еще больше.. И тогда эффективность алгоритма резко упадет..
Вот реализация алгоритма, который существенно повышает эффективность при сохранении случайности выбора: const Алгоритм, вроде, работает (хотя я уже практически сплю, могут быть ошибки.. ), но мне почему-то кажется, что он неоптимальный. Кто-нить может быстрее? При существенном увеличении размера доски буквы можно заменить на цифры. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Michael_Rybak |
Сообщение
#7
|
Michael_Rybak Группа: Пользователи Сообщений: 1 046 Пол: Мужской Реальное имя: Michael_Rybak Репутация: 32 |
Во-первых, 1000х1000 не получится из-за set.
А быстрее можно, используя специальную структуру данных, которая позволит находить нужную позицию за логарифмическое время. Т.е. будет n log n Могу дать ссылку где почитать, если интересно |
Lapp |
Сообщение
#8
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Могу дать ссылку где почитать, если интересно Фи, ссылка... А мозги на что? )) Да, с множествами я лопухнулся, понял наутро . 255 - и отвали.. Значит, надо иначе -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
Сообщение
#9
|
Гость |
Цитата 255 - и отвали.. Или реализуй BigSet (почему я и пользуюсь всегда Include/Exclude вместо +/-) и работай хоть до 10000 ... |
Michael_Rybak |
Сообщение
#10
|
Michael_Rybak Группа: Пользователи Сообщений: 1 046 Пол: Мужской Реальное имя: Michael_Rybak Репутация: 32 |
Цитата Фи, ссылка... Договорились - давайте придумывать |
Lapp |
Сообщение
#11
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Договорились - давайте придумывать Я некоторое время чувствовал себя некомфортно, как бы с долгом . Сегодня нашел минутку подумать над этой задачей. Вот результат.. Я привожу код, который заполняет массив [1..n] неповторяющимися случайными числами от 1 до n. Код не использует множеств, так что размер массива ограничен выбранным типом переменных (в ТР - по сути, размером блока). Код должен работать, мне кажется, быстрее предыдущего моего варианта. Принцип такой: - заполняем массив (RestNum) номерами по порядку (это те номера, которые остались); - в цикле выдергиваем из этого массива по одному элементу случайным образом и кладем в массив Num, заполняя его по порядку; - образовавщуюся в RestNum от изымания элемента дыру заполняем, сдвигая хвост массива на один элемент влево, начиная с номера сразу за дырой; - размер RestNum при этом как бы эффективно уменьшается на 1 (переменная m), что мы учитываем, уменьшая диапазон случайных чисел. Вот сам код. Его можно оформить в виде процедуры при желании . Если нужно только выводить номера на печать или в файл, то массив Num по сути не нужен, можно вдвое сэкономить память. const Сообщение отредактировано: Lapp - -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Michael_Rybak |
Сообщение
#12
|
Michael_Rybak Группа: Пользователи Сообщений: 1 046 Пол: Мужской Реальное имя: Michael_Rybak Репутация: 32 |
Lapp, +1. А я знаете как решил ее относительно недавно? За n log n. Берем группу, идем по ней, и разбиваем на две случайным образом: каждый элемент с равной вероятностью оказывается в первой или второй. Потом рекурсивно перемешиваем подгруппы, и сливаем вместе
Кстати, std::random_shuffle в C++ работает именно так, как вы описали. А что касается специальных структур данных, о которых я говорил - с их помощью можно работать с массивом, сохраняя порядок (не перемещая хвост в дырку). |
Текстовая версия | 23.12.2024 19:39 |