PAT_甲级_1114 Family Property

注意点

• 1、在输入的时候families的下标是从0开始到n-1结束，这样方便遍历输入的成员并进行信息计算
• 2、计算房子的平均面积和数目的时候，得使用总共的信息total_*除以家庭人数，因为该计算过程会执行多次。

AC代码

``````#include<cstdio>
#include<algorithm>
#include<vector>

using namespace std;

struct Family {
int ID;
int father;
int mother;
vector<int> children;
int estate;
int area;
} families[1001];

// 存储结果集
struct Node {
int ID;
int total_number;
double Avg_sets;
double Avg_area;
int total_sets;
int total_area;
bool flag;// 标记当前家庭
} nodes[10000];

bool cmp(const Node &a, const Node &b) {
return a.Avg_area != b.Avg_area ? a.Avg_area > b.Avg_area : a.ID < b.ID;
}

// 统计在[0,10000]中哪些是存在的成员
bool visited[10000];

// 记录每一个人的祖先(可能不在输入中)
int father[10000];

// 找到x的祖先，这里采用了压缩路径的方式
int findFather(int x) {
int a = x;
while (x != father[x]) {
x = father[x];
}
while (a != father[a]) {
int z = father[a];
father[a] = x;
a = z;
}
return x;
}

void Union(int a, int b) {
int fa = findFather(a);
int fb = findFather(b);
if (fa < fb) {
father[fb] = fa;
} else {
father[fa] = fb;
}
}

int main() {
for (int i = 0; i < 10000; ++i) {
father[i] = i;
}
int n;
scanf("%d", &n);
Family member;
int k;
for (int i = 0; i < n; ++i) {
scanf("%d %d %d %d", &member.ID, &member.father, &member.mother, &k);
int child;
for (int j = 0; j < k; ++j) {
scanf("%d", &child);
member.children.push_back(child);
visited[child] = true;
Union(member.ID, child);
}
scanf("%d %d", &member.estate, &member.area);
families[i] = member;
visited[member.ID] = true;
if (member.father != -1) {
visited[member.father] = true;
Union(member.ID, member.father);
}
if (member.mother != -1) {
visited[member.mother] = true;
Union(member.ID, member.mother);
}
}
// 将所有归类的家庭进行计算相关信息
for (int i = 0; i < n; ++i) {
int id = findFather(families[i].ID);
nodes[id].ID = id;
nodes[id].total_area += families[i].area;
nodes[id].total_sets += families[i].estate;
nodes[id].flag = true;
}
int num = 0;
// 统计家庭成员人数和家庭数目
for (int i = 0; i < 10000; ++i) {
if (visited[i]) {
int id = findFather(i);
++nodes[id].total_number;
}
if (nodes[i].flag) {
++num;
}
}
// 计算房子的平均面积和平均数目
for (int i = 0; i < 10000; ++i) {
if (visited[i]) {
int id = findFather(i);
nodes[id].Avg_area = nodes[id].total_area*1.0/nodes[id].total_number;
nodes[id].Avg_sets = nodes[id].total_sets*1.0/nodes[id].total_number;
}
}
printf("%d\n", num);
sort(nodes,nodes+10000,cmp);
for(int i=0;i<num;++i){
printf("%04d %d %.3f %.3f\n",nodes[i].ID,nodes[i].total_number,nodes[i].Avg_sets,nodes[i].Avg_area);
}
return 0;
}
``````

566 声望
15 粉丝
0 条评论