题目链接:PAT【甲级】1114
题目简述:给定每个⼈人的家庭成员和其⾃自⼰己名下的房产,要求统计出每个家庭的⼈人⼝口数、⼈人均房产⾯积及房产套数。家庭信息⾸先按⼈均⾯积降序输出,若有并列,则按成员编号的升序输出。
#include<bits/stdc++.h>
using namespace std;
unordered_map<int, int> areas, sets, members;
int father[10000], exist[10000], minID[10000];
struct node{
int id, Count;
double avgs, avga;
bool operator < (const node& p){
return avga == p.avga ? id < p.id : avga > p.avga;//这边比较还有待确定是否正确
}
};
int findFather(int a){
int x = a;
while(x != father[x]) x = father[x];
while(a != father[a]){//路径压缩【这边压不压不影响】
int t = father[a];
father[a] = x;
a = t;
}
return x;
}
void Union(int a, int b){
int x1 = findFather(a), x2 = findFather(b);
if(x1 != x2) father[x2] = x1;
}
int main(){
int n, id, fid, mid, k, cid, m, a;
cin >> n;
for (int i = 0; i < 10000; i++)
father[i] = i;
for (int i = 0; i < n; i++){
cin >> id >> fid >> mid >> k;
exist[id] = 1;//标记出现过
if(fid != -1){//合并树
Union(id, fid);
exist[fid] = 1;
}
if(mid != -1){
Union(id, mid);
exist[mid] = 1;
}
for (int j = 0; j < k;j++){
cin >> cid;
Union(id, cid);
exist[cid] = 1;
}
cin >> m >> a;
// areas[findFather(id)] += a;
// sets[findFather(id)] += m;
areas[id] = a;//记录房产信息
sets[id] = m;
}
fill(minID, minID + 10000, -1);//初始化
for (int i = 0; i < 10000;i++){
if(exist[i] == 1){//如果当前编号存在
int root = findFather(i);
members[root]++;
if(root != i){//避免重复累加
areas[root] += areas[i];
sets[root] += sets[i];
}
if(minID[root] > i || minID[root] == -1){//更新每个家庭的最小编号成员
minID[root] = i;
}
}
}
vector<node> v;
for (auto i = members.begin(); i != members.end();i++)
v.push_back({minID[i->first], members[i->first], 1.0 * sets[i->first] / members[i->first], 1.0 * areas[i->first] / members[i->first]});
sort(v.begin(), v.end());
cout << v.size() << endl;
for (int i = 0; i < v.size();i++)
printf("%04d %d %.3f %.3f\n", v[i].id, v[i].Count, v[i].avgs, v[i].avga);
return 0;
}
这个题目有两个关键点,分享一下:
- 不能够在数据输入的同时,去像这样来记录房产信息。
// areas[findFather(id)] += a;
// sets[findFather(id)] += m;
因为根节点时会变的。当数据不断的输入时,我们无法保证根节点还是原来的根节点,所以这里会出错的。必须先暂存下来,在后续的处理中来进行处理。
- 编号问题。有可能编号是为0的,所以我这边使用了数组,默认值为-1来规避掉这个问题。平时出于便利【其实也就那样】用
unordered_map
,这里边不好用了。