微软2017年预科生计划在线编程笔试-#1490 : Tree Restoration

http://hihocoder.com/problemset/problem/1490

题意理解:根据给的每一层的节点找到每个节点的父亲,注意右边的节点的父亲不能再左边节点的父亲的左边,所以就很简单了。考虑最后一层的父亲怎么找,其实就是挨着往后平移,当挨着的两个叶子距离相差==2的时候,父亲就一样,不然就找上一层接着往右边的第一个不是叶子结点的节点。然后为了之后上一层也有距离的关系,把这一层叶子节点和所有节点的距离关系-1作为他的父亲的距离关系,此时不对的距离关系只有这个节点的子树,可是之后是用不到的,没有关系,所以就可以每次算一层。

急转弯:考虑最后一层怎么做;利用儿子-1赋值给父亲。

算法:无。

数据结构:树,主要是挨着往后推,也没有用到树的知识。

from __future__ import print_function
#
#

'test for python'

__author__ = 'hjkruclion'

import os
import sys
import math

def read_int():
    """Read a seris of numbers."""
    return list(map(int, sys.stdin.readline().split()))

maxn = 100 + 10

N , M, K = read_int()

A = [0 for _ in range(maxn)]
# A = np.zeros([maxn], np.int)
d = [[0 for _ in range(maxn)] for x in range(maxn)]
# d = np.zeros([maxn, maxn], np.int)
fa = [0 for _ in range(maxn)]
# fa = np.zeros([maxn], np.int)
L = [0 for _ in range(maxn)]
# L = np.zeros([maxn], np.int)
isleave = [0 for _ in range(maxn)]
# isleave = np.zeros([maxn], np.int)
G = [[] for _ in range(maxn)]

t = read_int()
for i in range(1, M + 1):
    A[i] = t[i - 1]
for i in range(1, M + 1):
    t = read_int()
    for j in range(0, A[i]):
        G[i].append(t[j])
t = read_int()
for i in range(0, K):
    isleave[t[i]] = 1
    L[i + 1] = t[i]
for i in range(1, K + 1):
    t = read_int()
    for j in range(1, K + 1):
        d[L[i]][L[j]] = t[j - 1]
# print(d[6][7])
for i in reversed(range(2, M + 1)):
    nowfa = -1
    nowno = -1
    last = 0
    for j in range(0, len(G[i])):
        v = G[i][j]
        if last != 0 and d[last][v] == 2:
            fa[v] = fa[last]
            last = v
            continue
        nowno += 1
        nowfa = G[i - 1][nowno]
        while isleave[nowfa] == 1 and nowno + 1 < len(G[i - 1]):
            nowno += 1
            nowfa = G[i - 1][nowno]
        fa[v] = nowfa
        for z in range(1, N + 1):
            d[nowfa][z] = d[z][nowfa] = d[v][z] - 1
        last = v
for i in range(1, N + 1):
    print(fa[i], end=' ')
# print()





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值