PAT (Advanced Level) Practice 1114 Family Property (25 分)

1114 Family Property (25 分)

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 Child​1​​⋯Child​k​​ M​estate​​ Area

where ID is a unique 4-digit identification number for each person; Father and Mother are the ID's of this person's parents (if a parent has passed away, -1will be given instead); k (0≤k≤5) is the number of children of this person; Child​i​​'s are the ID's of his/her children; M​estate​​ is the total number of sets of the real estate under his/her name; and Area 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 AVG​sets​​ AVG​area​​

where ID is the smallest ID in the family; M is the total number of family members; AVG​sets​​ is the average number of sets of their real estate; and AVG​area​​ 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

题目大意:输入N个家族的成员、房产数量和面积,输出每个大家族中编号最小的人,家族成员数量,家族房产平均数量。

题解1:

思路:并查集。

对每个家族,输入的时候选择编号最小的人作为父亲,进行合并。

每个家族的第一个人,把房产数量和面积记到他的名下。

所有的家族输入后,更新所有人的父亲(保证每个人都找到了真正的父节点)。

遍历,找到每个家族的最小编号,把所有房产改到他的名下,并记录总家族数。

排序,输出。

注意事项:

1.比较的时候,由于每个人所记的家族成员数量、房产信息不一样(非父节点不记录家族成员数量),如果初始化成员数量,房产数量和面积都为0,会导致比较出错。修改:初始化成员数量为1(即他自己)(后面统计成员数量的时候注意不要重复加上父节点自己),初始化房产数量和面积都为0,用乘法代替除法进行房产面积平均值比较。

2.每个人的编号是一个4位数字,包括0000。

3.初始化book=-1,用来区分该编号的成员是否存在。

4.使用vector记录成员信息应该可以减少很多内存,不过这里用数组通过了,就暂时没有尝试vector。

源代码1:

#include<iostream>
#include<algorithm>
#include<map>
#include<stdlib.h>
#include<vector>
using namespace std;
struct node
{
	int id=10000, book = -1, cnt = 1, num = 0, area = 0;
};
bool cmp(node a, node b)
{
	if (a.area * b.cnt != b.area * a.cnt)return a.area * b.cnt > b.area * a.cnt;
	else return a.id < b.id;
}
node person[10001];
int getfather(int x)
{
	if (x == person[x].book)return x;
	else return person[x].book = getfather(person[x].book);
}
void merge(int x, int y)
{
	int fx, fy;
	fx = getfather(x);
	fy = getfather(y);
	if(fx<fy)person[fy].book = fx;
	else person[fx].book = fy;
	return;
}
int main()
{
	int n, k, htemp, ftemp, i, j,mmax=0;
	map<int, int>mmap;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		int self, others;
		scanf("%d", &self);
		if(person[self].book ==-1)person[self].book=person[self].id= self;
		for (j = 0; j < 2; j++)
		{
			scanf("%d", &others);
			if (others != -1)
			{
				if (person[others].book == -1)person[others].book = person[others].id = others;
				merge(self, others);
			}
		}
		scanf("%d", &k);
		for (j = 0; j < k; j++)
		{
			scanf("%d", &others);
			if (person[others].book == -1)person[others].book = person[others].id = others;
			merge(self,others);
		}
		scanf("%d %d", &person[self].num, &person[self].area);
	}
	for (i = 0; i <= 10000; i++)
		if(person[i].book!=-1)getfather(i);
	mmax = 0;
	for (i = 0; i < 10001; i++)
	{
		if (person[i].book != -1)
		{
			if (person[i].book == i)mmax++;
			else
			{
				person[person[i].book].num += person[i].num;
				person[i].num = 0;
				person[person[i].book].area += person[i].area;
				person[i].area = 0;
				person[person[i].book].cnt++;
			}
		}
	}
	sort(person, person+10001, cmp);
	printf("%d\n", mmax);
	for (i = 0; i < mmax; i++)
		printf("%04d %d %.3lf %.3lf\n", person[i].id, person[i].cnt, 1.0*person[i].num/person[i].cnt, 1.0*person[i].area/person[i].cnt);

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yi976263092/article/details/83626478