Найти тему
Соло путешествия

Python 3. Задача «Родословная: предки и потомки». Мое решение.

Python 3. Задача «Родословная: предки и потомки». Мое решение.

Условие задачи:

https://pythontutor.ru/lessons/dicts/problems/genealogy_ancestors_and_descendants/

"Даны два элемента в дереве. Определите, является ли один из них потомком другого.

Во входных данных записано дерево в том же формате, что и в предыдущей задаче Далее идет число запросов K. В каждой из следующих K строк, содержатся имена двух элементов дерева.

Для каждого такого запроса выведите одно из трех чисел: 1, если первый элемент является предком второго, 2, если второй является предком первого или 0, если ни один из них не является предком другого."

Решение:

# изначально нам известно число строк в словаре исходных данных

k = int(input()) # число строк ввода

A = dict() # словарь запросов

# циклом формируем словарь исходных данных

for i in range(k-1):

temp = input().split()

A[temp[0]] = temp[1]

k = int(input()) # число строк ввода

B = dict() # словарь запросов

for i in range(k):

temp = input().split()

B[temp[0]] = temp[1]

# вторым циклом сформировали словарь запросов

parents = A.values()

# сформировали список родителей

childrens = A.keys()

# сформировали список детей

for name in parents:

# перебираем имена отцов

# находим основателя рода

if name not in childrens:

first = name

del name

break

for key, val in B.items():

status = 0 # конечный результат

G = A.copy()

# создаем временный словарь для поиска

if key == first:

status = 1

print(status)

continue

# основатель рода является предком для всех

if val == first:

status = 2

print(status)

continue

# основатель рода является предком для всех

else:

# если нет прямой пары наследник - потомок и нет основателя рода

dad_key = G.pop(key) # родитель первого из рассматриваемой пары

dad_val = G.pop(val) # родитель второго из рассматриваемой пары

# вытащили предков из словаря G и удалили их строки методом pop

# первый раз команда всегда выполняется, т.к. идет после проверки

if dad_key == first:

while dad_val != first and len(G) > 0:

if A[dad_val] == key:

status = 1

print(status)

break

# второй является предком первого

else: dad_val = G.pop(dad_val)

# если в паре оказались, что не родственники:

if status == 1: continue # переходим к следующей паре

if status == 0:

print(status)

continue

if dad_val == first and status == 0:

while dad_key != first and len(G) > 0:

if A[dad_key] == val:

status = 2

print(status)

break

# второй является предком первого

else: dad_key = G.pop(dad_key)

# если цикл пройден, то не пара не родственники, выводим "0"

if status == 1: continue # переходим к следующей паре

if status == 0:

print(status)

continue

# если в паре оба младше второго поколения

while dad_key != first and len(G) > 0 and status == 0:

if A[dad_key] == val:

status = 2

print(status)

break

# второй является предком первого

else: dad_key = G.pop(dad_key)

# перебираем предков первого

# пока не найдем второго или основателя рода

# если не нашли, то обновляем словарь G и родителей пары

G = A.copy()

dad_key = G.pop(key)

dad_val = G.pop(val)

# и ищем дальше

while dad_val != first and len(G) > 0 and status == 0:

if A[dad_val] == key:

status = 1

print(status)

break

# второй является предком первого

else: dad_val = G.pop(dad_val)

# перебираем предков первого

# пока не найдем первого или основателя рода

if status < 1: print(status)

# если не нашли родственника, то выводим 0, конец цикла

P.S. если есть вопросы пишите комментарии, всем с радостью отвечу

-2