Я работаю над набором задач CSES, когда учусь программировать, и это решение было принято, но меня оно не совсем устраивало. Я просто знаю, что есть более быстрый способ проверить, действительно ли решение, вместо того, чтобы перебирать каждый элемент, и я уверен, что можно было бы внести еще много улучшений. Любые отзывы приветствуются!
Проблема: Перестановка целых чисел 1, 2,…, n называется красивой, если нет смежных элементов, разность которых равна 1. Для данного n построить красивую перестановку, если такая перестановка существует. Если решений несколько, вы можете распечатать любое из них. Если решений нет, выведите «NO SOLUTION».
def check_solution(sol):
last = sol[0]
for num in sol:
if num - last == 1 or num - last == -1:
return False
last = num
return True
a = [int(x) for x in range(1, int(input())+1)]
b = []
even = a[1::2]
odd = a[::2]
b.extend(even)
b.extend(odd)
if check_solution(b):
print(*b)
else:
print("NO SOLUTION")
1 ответ
Ваша идея нарезки списка хороша. Вы можете еще больше упростить, сделав что-то аналогичное с диапазонами, исключив большую часть необходимости в промежуточных переменных
def beautiful_permutation(n):
odd = list(range(1, n + 1, 2))
even = list(range(2, n + 1, 2))
return even + odd
Вашему валидатору, вероятно, следует проверить больше вещей, и его также можно упростить, воспользовавшись преимуществами abs(). При желании вы можете выразить проверку соседнего числа, используя all() и zip(). Мы все еще перебираем числа, но только более кратко.
def check_solution(n, sol):
return (
# Must not be empty.
sol and
# Must cover all intergers 1 through N.
set(range(1, n + 1)) == set(sol) and
# No adjacent numbers with difference of 1.
all(abs(a - b) != 1 for a, b in zip(sol, sol[1:]))
)
Еще один момент. Метод, используемый для создания последовательности, почти гарантирует достоверность. По определению, отдельные подсписки (odd и even) будет следовать правилу смежных чисел. Проблема может возникнуть только в месте соединения, где мы их склеиваем. Но наша функция может напрямую проверить проблему. Если вы добавите это и включите предварительную проверку на наличие неправильных или специальных входов (0, 1и т. д.), у вас будет функция, которая, по крайней мере, с практической точки зрения, доказуемо верна — валидатор не нужен!?!
if odd and even and abs(even[-1] - odd[0]) != 1:
return even + odd
else:
return None

Я думаю, что ваше «доказуемо правильное» решение неверно для n = 1.
— Келли Банди
@KellyBundy Похоже на дефиниционный случай. В любом случае OP может с этим разобраться.
— FMc
Супер полезные идеи! Я пытался решить эти проблемы, не ссылаясь слишком много в Интернете, и, учитывая мой недостаток опыта, это, к сожалению, обычно приводит к ненужным функциям или двум.
— Тайлер