четное дерево
Dec. 19th, 2016 10:44 amhttps://www.hackerrank.com/challenges/even-tree
По-русски: написать программу, которая получает с стандартного входа описание дерева, и печатает максимальное количество ребер, которые можно убрать так, чтобы дерево превратилось в лес, в котором в каждой компоненте связности четное число вершин. Пример и точное описание входа/выхода по ссылке.
По-моему, неплохой пример задачи для программистов, которая где-то на уровне интервью в Гугле. Мне сразу несколько вещей в ней нравится:
- надо знать/помнить что-то из теории (граф, дерево, компонента связности), но не глубокие вещи и не сложные алгоритмы, а достаточно для того, чтобы могло включиться алгоритмическое мышление
- надо сначала подумать, как собственно найти искомое, подход "прямиком" слишком трудоемкий
- сам выбираешь структуры данных, нет очевидно верного выбора, можно по-разному
- нужно сесть и написать с нуля работающий код, проверка проблемы "не знаю, как начать"
Я думаю, что если кто-то садится за эту проблему и меньше чем за час у него есть работающий код, то этот человек находится в хорошей форме в плане идти на технические интервью в Гугл/Фейсбук/Амазон итд. Все равно стоит готовиться, плюс еще есть интервью по system design, но для алго/кодинг это неплохие шансы, мне кажется. Конечно, люди, которые занимаются программистскими соревнованиями, щелкают такие задачки за 5-10 минут без проблем, но это другой случай, они натасканы на это. Я говорю про "просто программиста", который сомневается, идти ли на интервью и что там будет.
(чтобы проверить себя, я сел за эту задачу вчера, когда прочитал про нее. У меня был готова программа за 45 минут, включая проверку и отладку. Я пользовался https://repl.it/ для отладки, т.к. под рукой не было компилятора).
По-русски: написать программу, которая получает с стандартного входа описание дерева, и печатает максимальное количество ребер, которые можно убрать так, чтобы дерево превратилось в лес, в котором в каждой компоненте связности четное число вершин. Пример и точное описание входа/выхода по ссылке.
По-моему, неплохой пример задачи для программистов, которая где-то на уровне интервью в Гугле. Мне сразу несколько вещей в ней нравится:
- надо знать/помнить что-то из теории (граф, дерево, компонента связности), но не глубокие вещи и не сложные алгоритмы, а достаточно для того, чтобы могло включиться алгоритмическое мышление
- надо сначала подумать, как собственно найти искомое, подход "прямиком" слишком трудоемкий
- сам выбираешь структуры данных, нет очевидно верного выбора, можно по-разному
- нужно сесть и написать с нуля работающий код, проверка проблемы "не знаю, как начать"
Я думаю, что если кто-то садится за эту проблему и меньше чем за час у него есть работающий код, то этот человек находится в хорошей форме в плане идти на технические интервью в Гугл/Фейсбук/Амазон итд. Все равно стоит готовиться, плюс еще есть интервью по system design, но для алго/кодинг это неплохие шансы, мне кажется. Конечно, люди, которые занимаются программистскими соревнованиями, щелкают такие задачки за 5-10 минут без проблем, но это другой случай, они натасканы на это. Я говорю про "просто программиста", который сомневается, идти ли на интервью и что там будет.
(чтобы проверить себя, я сел за эту задачу вчера, когда прочитал про нее. У меня был готова программа за 45 минут, включая проверку и отладку. Я пользовался https://repl.it/ для отладки, т.к. под рукой не было компилятора).
no subject
Date: 2016-12-19 09:23 am (UTC)Может, я чего-то не понимаю, но, как мне кажется, подход "прямиком" в худшем случае даст О(n^2). Обходим дерево. Если все вершины, дочерние для данной, просмотрены, проверяем, можно ли убрать ребро от данной вершины к родителю. Если хоть одно ребро убрано, по завершению обхода повторяем процедуру. (впрочем, надо подумать - нужен ли этот последний шаг)
no subject
Date: 2016-12-19 09:57 am (UTC)(no subject)
From:no subject
Date: 2016-12-19 09:56 am (UTC)no subject
Date: 2016-12-19 11:18 am (UTC)no subject
Date: 2016-12-19 10:25 pm (UTC)(no subject)
From:no subject
Date: 2016-12-19 11:33 am (UTC)no subject
Date: 2016-12-19 02:13 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-12-19 11:36 am (UTC)Это странное состояние, не сразу обратил внимание. Как Вы дошли до жизни такой?
Или я чего-то не понимаю в условии, или
Date: 2016-12-19 12:06 pm (UTC)можно удалить все рёбра: тогда про каждую (отсутствующую) компоненту связности можно сказать что угодно.Да, я написал бред.
no subject
Date: 2016-12-19 12:12 pm (UTC)Кстати, как вам такое доказательство, хорошо или не очень?
0) Описание алгоритма: удаляем все те ребра, которые соединяют поддеревья с четным количеством вершин с их родителями.
1) Если дерево нечетное, то из него невозможно получить валидный (удовлетворяющий условиям задачи) вывод. Это очевидно.
2) Все те ребра, которые *вообще можно* удалить, чтобы получить на выходе только четные деревья, алгоритм удалит. Поэтому здесь нет никакой вариативности. А значит, этот алгоритм оптимален (удаляет максимальное число ребер).
no subject
Date: 2016-12-20 07:38 am (UTC)Мне кажется, ваше док-во "пропускает" факт, который я упомянул в этом комментарии, а его надо сказать в какой-то момент (например, если бы в условии было "нечетный" вместо "четный", то это условие бы не выполнялось, и решение, которое просто собирает все ребра-кандидаты, не обращая внимание на то, как они сочетаются друг с другом, не работало бы).
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-12-20 08:31 pm (UTC)(no subject)
From:no subject
Date: 2016-12-19 12:54 pm (UTC)no subject
Date: 2016-12-19 01:09 pm (UTC)(no subject)
From:(no subject)
From: (Anonymous) - Date: 2016-12-19 02:52 pm (UTC) - Expand(no subject)
From:no subject
Date: 2016-12-19 01:08 pm (UTC)no subject
Date: 2016-12-19 03:13 pm (UTC)no subject
Date: 2016-12-20 07:32 am (UTC)no subject
Date: 2016-12-20 11:34 am (UTC)http://ideone.com/km5UAv
no subject
Date: 2016-12-19 04:01 pm (UTC)no subject
Date: 2016-12-20 07:26 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-12-19 05:38 pm (UTC)no subject
Date: 2016-12-19 07:55 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-12-19 10:19 pm (UTC)Красим ребра в цвета 0 и 1 по правилу:
1) Ищем вершину, из которой выходит ровно одно некрашеное ребро (изначально все некрашеные). Если таких нет, удаляем ребра с цветом 1 и откланиваемся.
2) Единственное некрашеное ребро , выходящее из найденной вершины, красим в четность числа ребер, уже покрашенных в 0 и выходящих из той же вершины, и возвращаемся к пункту 1)
update Впрочем, начать нужно с проверки, что общее число вершин четное. Иначе задавший задачу посылается лесом.
no subject
Date: 2016-12-19 10:23 pm (UTC)У меня, наверное, больше часа получилось
Date: 2016-12-20 10:16 am (UTC)(А так как у них что попало нельзя импортировать,
пришлось заменить
from treelib import Node, Tree
на самодельную реализацию функциональности дерева.
(да, видимо, проще было бы обойтись без дерева вообще).
)
Идея в том, чтобы "приклеить" листья к их предкам, учитываю их (листьев) количество.
Повторять, пока не останется один корень, подсчитывая по дороге, сколько раз приклеивали лист чётного веса.
no subject
Date: 2016-12-20 06:54 pm (UTC)