✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
专栏地址:PAT题解集合
原题地址:题目详情 - 1114 Family Property (pintia.cn)
中文翻译:家产
专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞收藏,您的支持就是我创作的最大动力
This time, you are supposed to help us collect the data for family-owned property. Given each person’s family members, and the estate(房产)info under his/her own name, we need to know the size of each family, and the average area and number of sets of their real estate.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000). Then N lines follow, each gives the infomation of a person who owns estate in the format:
ID Father Mother k Child1⋯Childk Mestate Area
where
ID
is a unique 4-digit identification number for each person;Father
andMother
are theID
’s of this person’s parents (if a parent has passed away,-1
will be given instead); k (0≤k≤5) is the number of children of this person; Childi’s are theID
’s of his/her children; Mestate is the total number of sets of the real estate under his/her name; andArea
is the total area of his/her estate.Output Specification:
For each case, first print in a line the number of families (all the people that are related directly or indirectly are considered in the same family). Then output the family info in the format:
ID
M
AVGsets AVGareawhere
ID
is the smallest ID in the family;M
is the total number of family members; AVGsets is the average number of sets of their real estate; and AVGarea is the average area. The average numbers must be accurate up to 3 decimal places. The families must be given in descending order of their average areas, and in ascending order of the ID’s if there is a tie.Sample Input:
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
Sample Output:
3 8888 1 1.000 1000.000 0001 15 0.600 100.000 5551 4 0.750 100.000
给定每个人的家庭成员以及他/她自己名字下的不动产(地产)信息,我们需要知道每个家庭的成员数,以及人均不动产面积和人均房产套数。
输入拥有房产的人员的信息,格式如下:
ID Father Mother k Child_1 ... child_k M_estate Area
输出一个家庭的相关房产信息,格式如下:
ID M AVG_sets AVG_area
按人均房产面积降序顺序输出所有家庭信息。当存在人均房产面积相同的情况时,按 ID
升序顺序排序。
具体思路如下:
e
来存储所有关系,并用一个结构体 family
来存储每个家庭的相关信息,然后输入拥有房产的人员信息。res
中。ID
升序顺序排序。3
位小数。#include
using namespace std;
const int N = 10010;
int n, cnt;
int p[N], c[N], hc[N], ha[N];
bool st[N];
struct edge
{
int a, b;
}e[N];
struct family
{
int id, c, hc, ha;
//重载比较运算
bool operator < (const family& f)const
{
// ha / c 是否等于 f.ha / f.c
if (ha * f.c != f.ha * c) return ha * f.c > f.ha * c;
return id < f.id;
}
};
//并查集模板
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n;
//输入每个家庭信息
cnt = 0;
for (int i = 0; i < n; i++)
{
int id, father, mother, k;
cin >> id >> father >> mother >> k;
st[id] = true;
//判断是否有父母
if (father != -1) e[cnt++] = { id,father };
if (mother != -1) e[cnt++] = { id,mother };
//输入孩子信息
while (k--)
{
int x;
cin >> x;
e[cnt++] = { id,x };
}
cin >> hc[id] >> ha[id];
}
for (int i = 0; i < N; i++) p[i] = i, c[i] = 1; //初始化并查集
for (int i = 0; i < cnt; i++) //合并家庭
{
int a = e[i].a, b = e[i].b;
st[a] = true, st[b] = true;
int pa = find(a), pb = find(b);
if (pa != pb)
{
if (pa > pb) swap(pa, pb);
c[pa] += c[pb];
hc[pa] += hc[pb];
ha[pa] += ha[pb];
p[pb] = pa;
}
}
//统计答案
vector<family> res;
for (int i = 0; i < N; i++)
if (st[i] && p[i] == i)
res.push_back({ i,c[i],hc[i],ha[i] });
//对答案进行排序
sort(res.begin(), res.end());
cout << res.size() << endl;
for (auto& f : res)
printf("%04d %d %.3lf %.3lf\n", f.id, f.c, (double)f.hc / f.c, (double)f.ha / f.c);
return 0;
}