[PYTHON](PAT)1114 FAMILY PROPERTY(25 分)

43 篇文章 0 订阅

This time, you are supposed to help us collect the data for family-owned property. Given each person's family members, and the estate(房产)info under his/her own name, we need to know the size of each family, and the average area and number of sets of their real estate.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000). Then N lines follow, each gives the infomation of a person who owns estate in the format:

ID Father Mother k Child​1​​⋯Child​k​​ M​estate​​ Area

where ID is a unique 4-digit identification number for each person; Father and Mother are the ID's of this person's parents (if a parent has passed away, -1 will be given instead); k (0≤k≤5) is the number of children of this person; Child​i​​'s are the ID's of his/her children; M​estate​​ is the total number of sets of the real estate under his/her name; and Area is the total area of his/her estate.

Output Specification:

For each case, first print in a line the number of families (all the people that are related directly or indirectly are considered in the same family). Then output the family info in the format:

ID M AVG​sets​​ AVG​area​​

where ID is the smallest ID in the family; M is the total number of family members; AVG​sets​​ is the average number of sets of their real estate; and AVG​area​​ is the average area. The average numbers must be accurate up to 3 decimal places. The families must be given in descending order of their average areas, and in ascending order of the ID's if there is a tie.

Sample Input:

10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100

Sample Output:

3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

题目大意

给定一些人员信息,包括他们的父母,子女,有多少房产,总共多少面积。

要求按照格式输出一个家族的人员数量、人均拥有房产套数、人均拥有房产面积。最前面的识别符ID为家族中ID最小的那个人的。

分析

使用并查集,合并属于同一个家族的,在合并的过程中,更新房产信息。

首先将人员信息存储入info字典,将每条输入中的所有ID存储入man列表。

实例化unionfind实例。

使用items属性存储去重之后的所有人员的ID,使用item存储每次输入获取的当前行的所有ID。

使用root属性记录当前节点的根节点。使用result存储当前节点所属家族的房产总套数、总面积以及总人数。

在main()函数中调用实例u的create()方法。构建森林,合并集合。

item中的每一个元素来说,如果它包含了一个以上的元素,则遍历它。对它里面的元素进行遍历时,如果发现相邻的两个元素的根节点不同,就合并这两个节点。

比较这两个节点的根节点哪个比较小,将根节点比较大的那颗树合并到根节点较小的那棵树下面,更新小根节点的家族的信息,并删除大根节点。

Python实现

class unionfind:
    def __init__(self, man, info):
        self.items = []
        self.item, self.info = man, info
        for x in self.item:
            self.items += x
        self.items = list(set(self.items))
        self.root, self.result = {}, {}
        for x in self.items:
            self.root[x] = x
            try:
                self.result[x] = self.info[x][-2:]+[1]
            except:
                self.result[x] = [0,0,1]

    def create(self):
        for x in self.item:
            if len(x) > 1:
                for i  in range(1,len(x)):
                    root1, root2 = self.findroot(x[i-1]), self.findroot(x[i])
                    if root1 != root2:
                        self.union(root1, root2)
            
    def findroot(self, x):
        if x in self.result.keys():
            return x
        else:
            return self.findroot(self.root[x])
            
    def union(self, root1, root2):
        if root1<root2:
            self.root[root2] = root1
            self.result[root1][0] += self.result[root2][0]
            self.result[root1][1] += self.result[root2][1]
            self.result[root1][2] += self.result[root2][2]
            self.result.pop(root2)
        else:
            self.root[root1] = root2
            self.result[root2][0] += self.result[root1][0]
            self.result[root2][1] += self.result[root1][1]
            self.result[root2][2] += self.result[root1][2]
            self.result.pop(root1)
def main():
    n = int(input())
    info, man = {}, []
    for x in range(n):
        line = input().split(" ")
        ID, fa, mo = line[0], line[1] ,line[2]
        k, m, a = int(line[3]), int(line[-2]), int(line[-1])
        info[ID] = [m,a]
        unit = [ID]
        if fa !='-1':
            unit.append(fa)
        if mo !='-1':
            unit.append(mo)
        unit += line[4 : 4 + k]
        man.append(unit)
    u = unionfind(man,info)
    u.create()
    result = sorted(u.result, key = lambda x : (-u.result[x][1]/u.result[x][2],int(x)))
    print(len(result))
    for x in result:
        print(x,u.result[x][2],'{:.3f}'.format(u.result[x][0]/u.result[x][2]),'{:.3f}'.format(u.result[x][1]/u.result[x][2]))

if __name__ == "__main__":
    main()

 用Python做PAT,答案都在这儿了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值