1. 程式人生 > >PAT (Advanced Level) Practice 1114 Family Property (25 分)

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;
}