给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。
输入格式:
输入第一行给出一个正整数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
结尾无空行
思路:算法部分就是简单的并查集,但数据处理等方面还挺复杂,一定要仔细。首先用个data结构体数组来存储输入的每个人的信息,用node结构体来存储每个家族的信息,其中包括该家族最小成员编号,人数,人均房产数量和人均房产面积,其中flag用来标识家族是否存在,因为数据量不大,要注意编码细节(人数1005和家庭数10005的设置)。输入人的信息时,将他和其父母孩子合并,并使祖先的编号最小,用vis数组标记该编号是否出现。合并之后遍历n个人,将其房产信息都加入到家族结构体中,最后还要排序,先按人均房产面积降序排列,再按编号升序排列。
#include<bits/stdc++.h>
using namespace std;
struct data //存储输入的每个人的信息
{
int id, fa, ma, k, num, area;
int ch[6];
}a[1005];
struct node //存储每个家族的信息,flag用来标识是否存在
{
int idm, pp, flag;
double num, area;
}fam[10005];
int root[10005], vis[10005], n, res = 0; //res家庭数量
int getr(int x) {
if (root[x] == x)
return x;
else
return root[x] = getr(root[x]);
}
void Union(int x, int y) {
int xx = getr(x);
int yy = getr(y);
if (xx < yy)
root[yy] = xx;
else
root[xx] = yy;
}
bool cmp(node x, node y) {
if (x.area == y.area)
return x.idm < y.idm;
else
return x.area > y.area;
}
int main() {
cin >> n;
int i, j;
for (i = 0; i < 10000; i++) {
root[i] = i;
}
for (i = 0; i < n; i++) {
cin >> a[i].id >> a[i].fa >> a[i].ma >> a[i].k;
for (j = 0; j < a[i].k; j++)
cin >> a[i].ch[j];
cin >> a[i].num >> a[i].area;
vis[a[i].id] = 1;
if (a[i].fa != -1) {
vis[a[i].fa] = 1;
Union(a[i].id, a[i].fa);
}
if (a[i].ma != -1) {
vis[a[i].ma] = 1;
Union(a[i].id, a[i].ma);
}
for (j = 0; j < a[i].k; j++) {
vis[a[i].ch[j]] = 1;
Union(a[i].id, a[i].ch[j]);
}
}
for (i = 0; i < n; i++) {
int idr = getr(a[i].id);
fam[idr].idm = idr;
fam[idr].num += a[i].num;
fam[idr].area += a[i].area;
fam[idr].flag = 1;
}
for (i = 0; i < 10000; i++) {
if (vis[i])
fam[getr(i)].pp++;
if (fam[i].flag)
res++;
}
for (i = 0; i < 10000; i++) {
if (fam[i].flag) {
fam[i].num = fam[i].num * 1.0 / fam[i].pp;
fam[i].area = fam[i].area * 1.0 / fam[i].pp;
}
}
sort(fam, fam + 10000, cmp);
cout << res << endl;
for (i = 0; i < res; i++)
printf("%04d %d %.3f %.3f\n", fam[i].idm, fam[i].pp, fam[i].num, fam[i].area); //注意编号的输出
return 0;
}