субота, 16 квітня 2016 р.

Stepic.org 1.6 Наследование классов – Шаг 7




Вам дано описание наследования классов в следующем формате. 
<имя класса 1> : <имя класса 2> <имя класса 3> ... <имя класса k
>
Это означает, что класс 1 отнаследован от класса 2класса 3, и т. д.

Или эквивалентно записи:
class Class1(Class2, Class3 ... ClassK):
    pass
Класс A является прямым предком класса B, если B отнаследован от A:
class B(A):
    pass


Класс A является предком класса B, если 
  • A = B;
  • A - прямой предок B
  • существует такой класс C, что - прямой предок B и A - предок C

Например:
class B(A):
    pass

class C(B):
    pass

# A -- предок С


Вам необходимо отвечать на запросы, является ли один класс предком другого класса

Важное примечание:
Создавать классы не требуется.
Мы просим вас промоделировать этот процесс, и понять существует ли путь от одного класса до другого.

Формат входных данных

В первой строке входных данных содержится целое число n - число классов.
В следующих n строках содержится описание наследования классов. В i-й строке указано от каких классов наследуется i-й класс. Обратите внимание, что класс может ни от кого не наследоваться. Гарантируется, что класс не наследуется сам от себя (прямо или косвенно), что класс не наследуется явно от одного класса более одного раза.
В следующей строке содержится число q - количество запросов.
В следующих q строках содержится описание запросов в формате <имя класса 1> <имя класса 2>.
Имя класса – строка, состоящая из символов латинского алфавита, длины не более 50.

Формат выходных данных

Для каждого запроса выведите в отдельной строке слово "Yes", если класс 1 является предком класса 2, и "No", если не является. 
Sample Input:
4
A
B : A
C : A
D : B C
4
A B
B D
C D
D A
Sample Output:
Yes
Yes
Yes
No
Решение:
from collections import deque

def bfs(g, start):
    queue, enqueued = deque([(None, start)]), set([start])
    while queue:
        parent, n = queue.popleft()
        yield parent, n
        new = set(g[n]) - enqueued
        enqueued |= new
        queue.extend([(n, child) for child in new ])

def shortest_path(g, start, end):
    paths = {None : []}
    for parent, child in bfs(g, start):
        paths[child] = paths[parent] + [child]
        if child == end:
            return paths[child]
    return None
# поиск в ширину был найден на сайте аннимона
classes = {}
n = int(input())
for i in range(n):
    tmp = input()
    tmp = tmp.replace(":"," ").split()
#    print(tmp)
    classes[tmp[0]] = [] if len(tmp) == 1 else tmp[1:]
homeless = []
for i in classes.values():
    for j in i:
        if j not in classes.keys():
            homeless.append(j)
for i in homeless: classes[i] = []
fullclasses = []
for i in classes.items():
    fullclasses.append(i[0])
    for j in i[1]:
        fullclasses.append(j)
#print(classes)
#print(fullclasses)
n = int(input())
for i in range(n):
    l, r = input().split()
    if l == r:
        print("Yes")
    elif l not in fullclasses or r not in fullclasses:
        print("No")
    elif shortest_path(classes, r, l) == None:
        print("No")
    else:
        print("Yes")

1 коментар: