L2-007 家庭房产(python)(原创解法,应该非并查集)

from functools import cmp_to_key
def get_family():#临时家庭表f=[房产,面积,{人表}]
    #['1234', 2, 300, ['0002', '5678', '9012']]
    f = []
    t = []  # 临时人表
    f = list(input().split())
    f[3] = int(f[3])
    for j in range( f[3]):
        t.append(f.pop(4))
    t.extend([f[0],f[1], f[2]])
    t=set(t)
    f = [ int(f[4]), int(f[5]), t-{'-1'}]
    # print(f)
    return f
def Add_F(T,f,F):#拓展F,家庭f的合并
    # f = [1, 100, {'5678', '0002', '9012'}]
    # T = {'7777', '1234', '5551'}
    # F = [[2, 300, {'7777', '1234', '5551'}]]
    if f[2] & T == set():
        F.append(f)
    else:
        # 找对对应家族,并把家庭并入家族
        delt=[]
        for item in F:
            if item[2] & f[2] != set():#如果有交集
                #f遍历F,吃掉所有有关的家庭F[i],形成大家族f_plus
                f[0]+=item[0]
                f[1]+=item[1]
                f[2]=f[2]|item[2]
                delt.append(item)
        for item in delt:
            F.remove(item)
        F.append(f)
    T = T | f[2]
    return T


def cmp(x, y):
    # print("this is:",x[1]/len(x[2]),':',str(min(x[2])),y[1]/len(y[2]),':',str(min(y[2])))
    if x[1]/len(x[2]) > y[1]/len(y[2]):
        return 1
    elif x[1] == y[1]:
        if str(min(x[2])) < str(min(y[2])):
            return 1
        else:
            return -1
    else:
        return -1

T=set()#所有人,用于判别亲戚
F=[]#家族表
num=int(input())
for i in range(num):
    f=get_family()
    T=Add_F(T,f,F)
F.sort(key=cmp_to_key(cmp),reverse=True)
print(len(F))
for item in F:
    n=len(item[2])
    print(str(min(item[2])),n,"%.3f"%(item[0]/n),"%.3f"%(item[1]/n))
# print(F)
# print(len(F))
# print("T:",T)

这里主要使用了3个类型:

临时家庭表f=[房产,面积,{人表}],用来储存每一次读取的那一行,把个人和父母弄成一个集合

(此部分原代码中重点注释)

T={所有人},用于记录出现过的人,以此来判断新的f是在F中并入原有家族还是新建家族

家族表F=[各个家族]

本题测试用例时,F=[[1, 1000, {'8888'}], [9, 1500, {'1235', '1234', '0002', '9012', '6663', '3721', '2222', '0001', '2333', '6661', '2468', '5678', '0004', '1236', '6662'}], [3, 400, {'5552', '5551', '6666', '7777'}]]

[1,1000,{'8888'}]是一个家族,1个房,1000面积,只有8888一个人

相信读者根据这个例子应该能了解这个题目的数据结构了,数据处理源代码中有众多注释,希望读者能理解

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值