【CCCC】L2-007 家庭房产 (25分),并查集,结构统计

    科技2022-07-11  87

    problem

    L2-007 家庭房产 (25分) 给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。

    输入格式: 输入第一行给出一个正整数N(≤1000),随后N行,每行按下列格式给出一个人的房产:

    编号 父 母 k 孩子1 … 孩子k 房产套数 总面积 其中编号是每个人独有的一个4位数的编号;父和母分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k(0≤k≤5)是该人的子女的个数;孩子i是其子女的编号。

    输出格式: 首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:

    家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积 其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。

    输入样例: 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 输出样例: 3 8888 1 1.000 1000.000 0001 15 0.600 100.000 5551 4 0.750 100.000

    题意:给出n个人自己,父母,子女的编号,以及他自己的房产套数和面积求每个家庭的人口和人均房产数

    solution

    输入n个人的数据,把他们合并为家庭,并查集按照编号小的合并再开一个结构表示家庭,用并查集根节点做代表,扫一遍n个人统计家庭房产数量和面积,再扫一遍所有人的name统计家庭的人数扫一遍统计单位房产,并按照单位房产排序输出。 #include<bits/stdc++.h> using namespace std; const int maxn = 1010; const int maxnn = 10010; int vis[maxnn];//编号i有人 struct member{int name, dad, mum, chi[20]; int num, area;}mem[maxn]; struct family{int name, cnt; double num, area; bool flag;}fam[maxnn]; bool cmp(family a, family b){return a.area!=b.area?a.area>b.area:a.name<b.name;} int fa[maxnn]; //合并的时候是编号,所以maxnn void init(int n){for(int i = 1; i <= n; i++)fa[i]=i;} int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} void merge(int x, int y){//修改:按照最小编号合并 x=find(x);y=find(y);if(x>y)fa[x]=y;else if(x<y)fa[y]=x; } int main(){ int n; cin>>n; //1.输入n个人,合并到家庭,标记编号以统计家庭人数 init(maxnn); for(int i = 0; i < n; i++){ int k; cin>>mem[i].name>>mem[i].dad>>mem[i].mum>>k; vis[mem[i].name]++; if(mem[i].dad != -1){ merge(mem[i].name,mem[i].dad); vis[mem[i].dad]++; } if(mem[i].mum != -1){ merge(mem[i].name,mem[i].mum); vis[mem[i].mum]++; } for(int j = 0; j < k; j++){ cin>>mem[i].chi[j]; merge(mem[i].name,mem[i].chi[j]); vis[mem[i].chi[j]]++; } cin>>mem[i].num>>mem[i].area; } //2.分完家后,扫1遍n统计房产,扫2遍maxnn统计人数,扫3遍统计单位房产 for(int i = 0; i < n; i++){ int name = find(mem[i].name); fam[name].name = name; //fam[name].cnt++; fam[name].num += mem[i].num; fam[name].area += mem[i].area; fam[name].flag = true; } int people = 0; for(int i = 0; i < maxnn; i++){ if(vis[i]!=0)fam[find(i)].cnt++; if(fam[i].flag)people++; } cout<<people<<"\n"; for(int i = 0; i < maxnn; i++){ if(fam[i].flag==1){ fam[i].num /= fam[i].cnt; fam[i].area /= fam[i].cnt; } } //3.按照单位房产排序输出 sort(fam,fam+maxnn,cmp); for(int i = 0; i < people; i++) printf("d %d %.3f %.3f\n", fam[i].name, fam[i].cnt, fam[i].num, fam[i].area); return 0; }
    Processed: 0.073, SQL: 8