L2-007 家庭房产
思路在代码里
#include <bits/stdc++.h>
using namespace std;
#define int long long
using pii=pair<int,int>;
int fa[10005];
set<int>peo;//存放出现过的人的编号
struct node{
int apt;//房产
int mj;//面积
}house[10005];
void chs()//并查集初始化
{
for(int i=1;i<=10005;i++) fa[i]=i;
}
struct infor{//存储答案格式
int minid;
int sum;
int apt;
int mj;
};
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
x=find(x),y=find(y);
if(x<y){//编号小的当祖先
fa[y]=x;
}else{
fa[x]=y;
}
}
map<int,infor>ans;//暂时存储 方便后面放到vector里面
void solve()
{
//总体的思路就是:并查集用来集合有关系的,并且以家庭的最小编号为祖先
//每次插入一个人都要进行合并,信息输入完以后就进行统计
//通过遍历set,找到各自的祖先,在ans中统计对应家庭的信息,最后按照排序规则输出即可
chs();
int n; cin>>n;
for(int i=0;i<n;i++)
{
int id,fu,mu,k;
cin>>id>>fu>>mu>>k;
peo.insert(id);
if(fu!=-1){
peo.insert(fu);
merge(id,fu);
}
if(mu!=-1){
peo.insert(mu);
merge(id,mu);
}
while(k--)
{
int x;
cin>>x;
peo.insert(x);
merge(id,x);
}
cin>>house[id].apt>>house[id].mj;
}
for(auto i:peo){
int zx=find(i);//最小编号祖先
ans[zx].minid=zx;//家庭成员中的最小编号
ans[zx].sum++;//家庭的总人口数
ans[zx].apt+=house[i].apt;//总房产
ans[zx].mj+=house[i].mj;//总面积
}
vector<infor>ve;
for(auto [x,y]:ans){
ve.push_back(y);
}
sort(ve.begin(),ve.end(),[](infor a,infor b){
if(1.0*a.mj/a.sum!=1.0*b.mj/b.sum) return 1.0*a.mj/a.sum>1.0*b.mj/b.sum;
return a.minid<b.minid;
});
cout<<ve.size()<<"\n";
for(int i=0;i<ve.size();i++)
{
printf("%04d %d %.3lf %.3lf\n",ve[i].minid,ve[i].sum,1.0*ve[i].apt/ve[i].sum,1.0*ve[i].mj/ve[i].sum);
}
}
signed main()
{
int t=1;
//cin>>t;
while(t--) solve();
}
posted on 2025-04-06 14:39 swj2529411658 阅读(13) 评论(0) 收藏 举报
浙公网安备 33010602011771号