L2-007 家庭房产 (25 分)
 

给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。

输入格式:

输入第一行给出一个正整数N(≤),随后N行,每行按下列格式给出一个人的房产:

编号 父 母 k 孩子1 ... 孩子k 房产套数 总面积

其中编号是每个人独有的一个4位数的编号;分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k0k≤)是该人的子女的个数;孩子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

 

并查集经典题 要稍微改写一下unite函数

PTA经典特色题目 算法不难 倒腾起来麻烦 还给要整个排序 还考察了STL的用法(= =)

推荐做

unite要改写一下 id最小的作为根节点

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <map>
 4 #include <set>
 5 #include <algorithm>
 6 using namespace std;
 7 int N, M, K;
 8 const int si = 10007;
 9 int par[si];
10 int cnt[si];
11 double area[si];
12 int housenum[si];
13 bool vis[si];
14 struct node {
15     int id, num;
16     double avgnum, avgarea;
17     
18 }no[si];
19 
20 bool cmp (node a, node b) {
21     if (a.avgarea != b.avgarea) return a.avgarea > b.avgarea;
22     return a.id < b.id;
23 }
24 using namespace std;
25 
26 int find(int x) {
27     if (x == par[x]) return par[x];
28     return par[x] = find(par[x]);
29 }
30 bool same(int x, int y) {
31     return find(x) == find(y);
32 }
33 void unite(int x, int y) {
34     x = find(x);
35     y = find(y);
36     if (x == y) return;
37     if (x < y) {
38         par[y] = par[x];
39     }
40     else {
41         par[x] = par[y];
42     }
43 }
44 int main() {
45     cin >> N;
46     for (int i = 0; i < si; i++) par[i] = i;
47     
48     int f, m, id, k, tp;
49     for (int i = 0; i < N; i++) {
50         cin >> id >> f >> m >> k;
51         if (f != -1) {
52             unite(id, f);
53             vis[f] = 1;
54         }
55         if (m != -1) {
56             unite(id, m);
57             vis[m] = 1;
58         }
59         vis[id] = 1;
60         for (int j = 0; j < k; j++) {
61             scanf("%d", &tp);
62             unite(id, tp);
63             vis[tp] = 1;
64         }
65         cin >> housenum[id] >> area[id];
66     }
67     set<int> st;
68     for (int i = 0; i < si; i++) {
69         if (!vis[i]) continue;
70         int x = find(i);//这个家庭
71         cnt[x]++;//人口数++
72         if (x != i) {
73              area[x] += area[i];
74              housenum[x] += housenum[i];
75         }
76         st.insert(x);
77     }
78     set<int>:: iterator it = st.begin();
79     int count = 0;
80     while (it != st.end()) {
81         int x = *it;
82         no[count].id = x;
83         no[count].num = cnt[x];
84         no[count].avgnum = housenum[x] * 1.0 / cnt[x];
85         no[count++].avgarea = area[x] * 1.0 / cnt[x];
86         it++;
87     }
88     cout << count << endl;
89     sort (no, no + count, cmp);
90     for (int i = 0; i < count; i++) {
91         printf("%04d %d %.3f %.3f\n", no[i].id, no[i].num, no[i].avgnum, no[i].avgarea);
92     }
93     return 0;
94 }