题目要求
翻译
给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积。其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。
代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<set>
#define MAX_ID 10000
#define MAX_N 1000
using namespace std;
int Rank[MAX_ID],parent[MAX_ID],estate[MAX_ID],area[MAX_ID];
set<int> ids;
struct Family
{
int id,cnt;
float avgSets,avgArea;
Family(int id,int cnt,float avgSets,float avgArea) : id(id),cnt(cnt),avgSets(avgSets),avgArea(avgArea){}
};
bool cmp(Family f1,Family f2)
{
return f1.avgArea!=f2.avgArea?f1.avgArea>f2.avgArea:f1.id<f2.id;
}
void init()
{
for(int i=0;i<MAX_ID;i++)
{
parent[i]=i;
}
memset(Rank,0,sizeof(int));
}
int find(int p)
{
while (p!=parent[p])
{
parent[p]=parent[parent[p]];
p=parent[p];
}
return p;
}
void Union(int p,int q)
{
if(p==-1||q==-1) return;
int f1=find(p),f2=find(q);
if(f1==f2) return;//根节点相同不需要合并
if(Rank[f1]>Rank[f2]){
parent[f2]=f1;
}else if(Rank[f1]<Rank[f2]){
parent[f1]=f2;
}else
{
parent[f2]=f1;
Rank[f1]++;
}
}
int main()
{
init();
int n;
cin>>n;
for(int i=0,id,f,m,k,e,a;i<n;i++)
{
scanf("%d %d %d %d",&id,&f,&m,&k);
Union(id,f);
Union(id,m);
ids.insert(id);
ids.insert(f);
ids.insert(m);
int child;
while(k--){
scanf("%d",&child);
Union(id,child);
ids.insert(child);
}
scanf("%d %d",&e,&a);
estate[id]=e;
area[id]=a;
}
ids.erase(-1);//记得擦除-1
vector<int> tmp[MAX_ID];
vector<Family> families;
for(int id:ids){
tmp[find(id)].emplace_back(id);
}
for(int id:ids)
{
if(tmp[id].empty()) continue;
vector<int>& member = tmp[id];
int totalArea=0,totalEstate=0,cnt=member.size(),familyId=member[0];
for(int m:member)
{
if(m<familyId) familyId=m;
totalArea+=area[m];
totalEstate+=estate[m];
}
families.push_back(Family(member[0],cnt,(float)totalEstate/cnt,(float)totalArea/cnt));
}
sort(families.begin(),families.end(),cmp);
cout<<families.size()<<endl;
for(Family f:families){
printf("%04d %d %.3f %.3f\n",f.id,f.cnt,f.avgSets,f.avgArea);
}
system("pause");
}
思路
需要用到并查集。
为数不多的PAT还在考的模板题目。建议先去B站看看并查集的视频讲解。回过头来看代码就很明了了。