题目详情
给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。
输入格式:
输入第一行给出一个正整数N(≤1000),随后N行,每行按下列格式给出一个人的房产:
编号 父 母 k 孩子1 … 孩子k 房产套数 总面积
其中编号是每个人独有的一个4位数的编号;父和母分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k(0≤k≤5)是该人的子女的个数;孩子i是其子女的编号。
输出格式:
首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:
家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积
其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。
代码实现
#include<iostream>
#include<algorithm>
using namespace std;
int mark[10003]={0},visit[10003]={0};
int find(int x){
if(mark[x]==x)return x;
else return find(mark[x]);
}
struct P{
int mianji,count,sum;//怎么把这些人归到一个家庭里?并查集???
int fa,ma;
//vector<int> son;
P(){
fa=-1;ma=-1;count=0;mianji=0;sum=0;
}
}people[10003];
struct A{
int id;
float count,mianji,renshu;//房子数量
A(){
id=-1;
count=0;
mianji=0;
renshu=0;
}
}ans[10003];
int markans[10003]={0};
int cmp1(A a, A b) {//对答案进行排序
if(a.renshu!=0&&b.renshu!=0)
if(a.mianji/a.renshu != b.mianji/b.renshu)
return a.mianji/a.renshu > b.mianji/b.renshu;
else
return a.id < b.id;
else if(a.renshu!=0)return 1;
return 0;
}
int main(){
for(int i=1;i<=10002;i++)mark[i]=i,ans[i].id=i;
int cnt=0;
int n;
cin>>n;int num[n]={0};
for(int i=0;i<n;i++){
cin>>num[i];
visit[num[i]]=1;
cin>>people[num[i]].fa>>people[num[i]].ma;
if(people[num[i]].fa!=-1){
visit[people[num[i]].fa]=1;
find(mark[people[num[i]].fa])<find(mark[num[i]])?(mark[find(mark[num[i]])]=find(mark[people[num[i]].fa])):(mark[find(people[num[i]].fa)]=find(mark[num[i]]));
//寻找序号最小的那个人
}if(people[num[i]].ma!=-1){
visit[people[num[i]].ma]=1;
find(mark[people[num[i]].ma])<find(mark[num[i]])?(mark[find(mark[num[i]])]=find(mark[people[num[i]].ma])):(mark[find(people[num[i]].ma)]=find(mark[num[i]]));
}
int kid;
cin>>kid;
for(int j=0;j<kid;j++){
int tmp;
cin>>tmp;
visit[tmp]=1;//方便统计人数
find(mark[tmp])<find(mark[num[i]])?(mark[num[i]]=find(mark[tmp])):(mark[tmp]=find(mark[num[i]]));
//people[num].son.push(tmp);
}
cin>>people[num[i]].count>>people[num[i]].mianji;
}
for(int i=0;i<10000;i++){
if(visit[i]){
if(ans[find(i)].renshu==0)cnt++;ans[find(i)].renshu++;
}
}
for(int i=0;i<n;i++){
int id=find(num[i]);
ans[id].id=id;
ans[id].mianji+=people[num[i]].mianji;
ans[id].count+=people[num[i]].count;
//ans[id].renshu++;
markans[id]=1;
}
sort(ans,ans+10000,cmp1);
cout<<cnt<<endl;
for(int i=0;i<10000;i++){
if(markans[ans[i].id])printf("%04d %d %.3f %.3f\n",ans[i].id,(int)ans[i].renshu,ans[i].count/ans[i].renshu,ans[i].mianji/ans[i].renshu);
}
}
算法思路
通过并查集找到一个家庭中最小的那个人,最后再以这个人为根,对所有人的房产,人数,面积进行统计。重点是并查集的使用。