题目:
给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。
输入格式:
输入第一行给出一个正整数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
三个核心map
1:并查集使用;存储上级与集合人数
2:存储面积
3:存储套数
map<string ,pair<string,int> >mp;
map<string ,double>mj;
map<string ,double >tao;
并查集过程在合并中计算集合人数当!mp.count(s)时表示出现一个全新 的人集合加一
每进行一次合并代表一个集合消失同时题目要求输出最小的name所以合并时以小为上级
ans存储集合数量
int ans;
string find(string a){
if(a=="-1")return "";
if(!mp.count(a)){
ans++;
mp[a]={a,1};
// cout<<a<<"ans加一"<<endl;
}
if(mp[a].first!=a){
mp[a].first=find(mp[a].first);
}
return mp[a].first;
}
void merge(string a,string b){
string a_f=find(a);
string b_f=find(b);
if(a=="-1"||b=="-1"){
return ;
}
if(a_f!=b_f){
if(a_f<b_f){
mp[b_f].first=a_f;
mp[a_f].second+=mp[b_f].second;
mp[b_f].second=0;
}
if(b_f<a_f){
mp[a_f].first=b_f;
mp[b_f].second+=mp[a_f].second;
mp[a_f].second=0;
}
ans--;
// cout<<a<<"ans减一"<<b<<endl;
}
return ;
}
在读入n存储好信息后,遍历mp整合mj与tao
同时找出各个集合的代表
for(int i=0;i<n;i++){
string id,idf,idm;
cin>>id>>idf>>idm;
find(id);
if(idf!="-1")merge(id,idf);
if(idm!="-1")merge(id,idm);
int k;
cin>>k;
for(int i=0;i<k;i++){
string hz;
cin>>hz;
merge(hz,id);
}
double mjj;
double taoo;
cin>>taoo>>mjj;
mj[id]+=mjj;
tao[id]+=taoo;
}
for(auto it:mp){
string it_f=find(it.first);
if(it.first==it_f){
zu.push_back(it.first);
}else{
mj[it_f]+=mj[it.first];
mj[it.first]=0;
tao[it_f]+=tao[it.first];
tao[it.first]=0;
}
}
按照题目要求对各个集合进行排序
bool cmp(string a,string b){
if(mj[a]/mp[a].second != mj[b]/mp[b].second){
return mj[a]/mp[a].second > mj[b]/mp[b].second;
}
return a<b;
}
sort(zu.begin(),zu.end(),cmp);
完整代码
#include<bits/stdc++.h>
using namespace std;
map<string ,pair<string,int> >mp;
map<string ,double>mj;
map<string ,double >tao;
int ans;
string find(string a){
if(a=="-1")return "";
if(!mp.count(a)){
ans++;
mp[a]={a,1};
// cout<<a<<"ans加一"<<endl;
}
if(mp[a].first!=a){
mp[a].first=find(mp[a].first);
}
return mp[a].first;
}
void merge(string a,string b){
string a_f=find(a);
string b_f=find(b);
if(a=="-1"||b=="-1"){
return ;
}
if(a_f!=b_f){
if(a_f<b_f){
mp[b_f].first=a_f;
mp[a_f].second+=mp[b_f].second;
mp[b_f].second=0;
}
if(b_f<a_f){
mp[a_f].first=b_f;
mp[b_f].second+=mp[a_f].second;
mp[a_f].second=0;
}
ans--;
// cout<<a<<"ans减一"<<b<<endl;
}
return ;
}
bool cmp(string a,string b){
if(mj[a]/mp[a].second != mj[b]/mp[b].second){
return mj[a]/mp[a].second > mj[b]/mp[b].second;
}
return a<b;
}
int main(){
vector<string >zu;
int n;
cin>>n;
ans=0;
for(int i=0;i<n;i++){
string id,idf,idm;
cin>>id>>idf>>idm;
find(id);
if(idf!="-1")merge(id,idf);
if(idm!="-1")merge(id,idm);
int k;
cin>>k;
for(int i=0;i<k;i++){
string hz;
cin>>hz;
merge(hz,id);
}
double mjj;
double taoo;
cin>>taoo>>mjj;
mj[id]+=mjj;
tao[id]+=taoo;
}
for(auto it:mp){
string it_f=find(it.first);
if(it.first==it_f){
zu.push_back(it.first);
}else{
mj[it_f]+=mj[it.first];
mj[it.first]=0;
tao[it_f]+=tao[it.first];
tao[it.first]=0;
}
}
cout<<ans<<endl;
sort(zu.begin(),zu.end(),cmp);
for(int i=0;i<zu.size();i++){
string now=zu[i];
cout<<now<<' '<<mp[now].second<<' ';
printf("%.3f ",tao[now]/mp[now].second);
printf("%.3f\n",mj[now]/mp[now].second);
}
return 0;
}