【刷题-PAT】A1114 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 child1 child2 ... childk M 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, -1
will 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; Mestate 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; AVGsets is the average number of sets of their real estate; and AVGarea 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
分析:要将每个家庭的数据分离出来,使用并查集即可实现,数据处理上有两种方法:
1.先将录入的数据按照输入的形式存在数组中,录入的同时完成集合的合并,然后再从录入的数据中挑出需要的数据,最后对挑出的数据仓晒礼输出;
2.在录入的同时进行集合的合并,并将数据按照输出的格式存储,然后进行处理
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<unordered_map>
#include<set>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int nmax = 10100;
int fath[nmax];
void init(){
for(int i = 0; i < nmax; ++i)fath[i] = i;
}
int findF(int x){
int z = x;
while(x != fath[x])x = fath[x];
while(z != fath[z]){
int temp = fath[z];
fath[z] = x;
z = temp;
}
return x;
}
void Union(int a, int b){
int fa = findF(a), fb = findF(b);
if(fa < fb)fath[fb] = fa;
else if(fa > fb)fath[fa] = fb;
}
struct node{
int id, people;
double num, area;
bool flag = false;
bool operator < (node &a)const{
return area != a.area ? area > a.area : id < a.id;
}
}ans[nmax];
struct data{
int id, fid, mid, k;
int child[6];
int num, area;
}v[nmax];
bool vis[nmax] = {false};
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
init();
int N;
scanf("%d", &N);
//录入数据并合并,由于序号不连续,要标记哪些序号已经出现过
for(int i = 0; i < N; ++i){
int id, fid, mid, k;
scanf("%d%d%d%d", &id, &fid, &mid, &k);
v[id].id = id;
v[id].fid = fid;
v[id].mid = mid;
v[id].k = k;
vis[id] = true;
if(fid != -1){
Union(id, fid);
vis[fid] = true;
}
if(mid != -1){
Union(id, mid);
vis[mid] = true;
}
for(int j = 0; j < k; ++j){
scanf("%d", &v[id].child[j]);
Union(id, v[id].child[j]);
vis[v[id].child[j]] = true;
}
scanf("%d%d", &v[id].num, &v[id].area);
}
//统计并抽出需要的数据,用flag标记该根节点是否已经出现
int cnt = 0;
for(int i = 0; i < nmax; ++i){
if(vis[i] == true){
int index = findF(i);
ans[index].id = index;
ans[index].people++;
ans[index].num += v[i].num;
ans[index].area += v[i].area;
if(ans[index].flag == false)cnt++;
ans[index].flag = true;
}
}
//处理
for(int i = 0; i < nmax; ++i){
if(ans[i].flag == true){
ans[i].num /= ans[i].people;
ans[i].area /= ans[i].people;
}
}
//排序输出
sort(ans, ans + nmax);
printf("%d\n", cnt);
for(int i = 0; i < cnt; ++i){
printf("%04d %d %.3f %.3f\n", ans[i].id, ans[i].people, ans[i].num, ans[i].area);
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int Nmax = 10000;
int father[Nmax];
bool vis[Nmax] = {false};
struct node{
int id, peoNum;
double Sav, Aav;
};
void init(){
for(int i = 0; i < Nmax; ++i)father[i] = i;
}
int findF(int x){
int z = x;
while(x != father[x])x = father[x];
while(z != father[z]){
int temp = father[z];
father[z] = x;
z = temp;
}
return x;
}
void Union(int a, int b){
int fa = findF(a), fb = findF(b);
if(fa != fb)father[fb] = fa;
}
bool cmp(node a, node b){
bool flag = false;
if(a.Aav / a.peoNum > b.Aav / b.peoNum){
flag = true;
}else if(a.Aav / a.peoNum == b.Aav / b.peoNum && a.id < b.id){
flag = true;
}
return flag;
}
int main(){
init();
int N = 0;
vector<node>v, v2;
scanf("%d", &N);
for(int i = 0; i < N; ++i){
int f, m, id, k, idm = 10000;
int peonum = 0;
scanf("%d%d%d%d", &id, &f, &m, &k);
if(f == -1 && m == -1)idm = id;
if(f == -1 && m != -1)idm = min(id, m);
if(f != -1 && m == -1)idm = min(id, f);
if(f != -1 && m != -1)idm = min(min(m, f), id);
if(!vis[id]){
peonum = 1;
vis[id] = true;
}
if(f != -1){
Union(f, id);
if(!vis[f]){
peonum++;
vis[f] = true;
}
}
if(m != -1){
Union(m, id);
if(!vis[m]){
peonum++;
vis[m] = true;
}
}
for(int j = 0; j < k; ++j){
int child;
scanf("%d", &child);
idm = min(idm, child);
Union(id, child);
if(!vis[child]){
peonum++;
vis[child] = true;
}
}
int setNum, area;
scanf("%d%d", &setNum, &area);
int flag = false;
for(int j = 0; j < v.size(); ++j){
if(findF(v[j].id) == findF(idm)){
v[j].id = min(idm, v[j].id);
v[j].peoNum += peonum;
v[j].Sav += (double)setNum;
v[j].Aav += (double)area;
flag = true;
break;
}
}
if(!flag)v.push_back({idm, peonum , (double)setNum, (double)area});
}
//录入数据的时候只合并了一部分家庭,再合并一遍
v2.push_back(v[0]);
for(int i = 1; i < v.size(); ++i){
int flag = false;
for(int j = 0; j < v2.size(); ++j){
if(findF(v[i].id) == findF(v2[j].id)){
v2[j].id = min(v[i].id, v2[j].id);
v2[j].peoNum += v[i].peoNum;
v2[j].Sav += v[i].Sav;
v2[j].Aav += v[i].Aav;
flag = true;
break;
}
}
if(!flag)v2.push_back(v[i]);
}
cout<<v2.size()<<endl;
sort(v2.begin(), v2.end(), cmp);
for(int i = 0; i < v2.size(); ++i){
printf("%04d %d %.3f %.3f\n", v2[i].id, v2[i].peoNum, v2[i].Sav / v2[i].peoNum, v2[i].Aav / v2[i].peoNum);
}
return 0;
}
【刷题-PAT】A1114 Family Property (25 分)的更多相关文章
- PTA PAT排名汇总(25 分)
PAT排名汇总(25 分) 计算机程序设计能力考试(Programming Ability Test,简称PAT)旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,科 ...
- 【刷题-PAT】A1126 Eulerian Path (25 分)
1126 Eulerian Path (25 分) In graph theory, an Eulerian path is a path in a graph which visits every ...
- 【刷题-PAT】A1101 Quick Sort (25 分)
1101 Quick Sort (25 分) There is a classical process named partition in the famous quick sort algorit ...
- PAT 甲级 1029 Median (25 分)(思维题,找两个队列的中位数,没想到)*
1029 Median (25 分) Given an increasing sequence S of N integers, the median is the number at the m ...
- PAT 甲级 1070 Mooncake (25 分)(结构体排序,贪心,简单)
1070 Mooncake (25 分) Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autum ...
- PAT 甲级 1078 Hashing (25 分)(简单,平方二次探测)
1078 Hashing (25 分) The task of this problem is simple: insert a sequence of distinct positive int ...
- PAT 甲级 1032 Sharing (25 分)(结构体模拟链表,结构体的赋值是深拷贝)
1032 Sharing (25 分) To store English words, one method is to use linked lists and store a word let ...
- PAT 1051 Pop Sequence (25 分)
返回 1051 Pop Sequence (25 分) Given a stack which can keep M numbers at most. Push N numbers in the ...
- 【刷题-PAT】A1108 Finding Average (20 分)
1108 Finding Average (20 分) The basic task is simple: given N real numbers, you are supposed to calc ...
随机推荐
- java 多线程:Thread类;Runnable接口
1,进程和线程的基本概念: 1.什么是进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机 ...
- winpcap 静默安装
前几天做一个小工具用到winpcap,由于有些用户系统未必安装过这个而领导要求尽量减少用户点击,于是只好想办法静默安装了,csdn搜了,貌似没有好用的,求助stackoverflow,还好,在某篇解答 ...
- cmake以源码的方式引入第三方项目
最前 本文将介绍一种以源码的方式引入第三方库的方法 准备 主项目,需要引用第三方库的某些函数 第三方库,以源码的形式提供给主项目使用 注意: 本文的背景:已经将第三方源码下载好. 一个例子 我这里准备 ...
- 【LeetCode】221. Maximal Square 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址: https://leet ...
- 【LeetCode】763. Partition Labels 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode.com/pr ...
- 涛思数据 TDengine集群搭建
一.准备 1.设置主机名 hostnamectl set-hostname a.com hostnamectl set-hostname b.com hostnamectl set-hostname ...
- MySQL 中的各种锁机制
行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁. 行级锁能大大减少数据库操作的冲突.其加锁粒度最小,但加锁的开销也最大.行级锁分为共享锁和排他锁. 特点 开销大,加锁 ...
- Java编程基础
JDK与JRE有什么区别 JDK:Java开发工具包(Java Development Kit),提供了Java的开发环境和运行环境. JRE:Java运行环境(Java Runtime Enviro ...
- 使用 Eclipse 可视化插件 windowbuilder 进行Java GUI开发(插件安装的两种方法)
对于Java GUI开发 其实最方便的方法是用插件制作,当然先了解完代码原理是最好的. eclispe安装windowbuilder有两种方式,一种是离线安装,一种是在线安装. 一.第一种在线安装: ...
- [学习笔记] Oracle字符串函数、日期函数、数值函数、转换函数、聚合函数
函数 单行函数:对一行数据进行操作的函数,如字符串函数.数值函数.转换函数.日期函数等. 聚合函数:同时对多行数据进行操作,如求和函数等. 字符串函数 函数 说明 ASCII(X) 求字符X的ASCI ...