PAT甲级1114

本文介绍PAT甲级1114题目的解决思路,通过DFS算法或并查集来确定家庭成员关系,计算家庭总数及各家庭的具体指标,并按要求进行排序输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PAT甲级1114

题目大意:给出n组数据,每行给出当前人员的id,父母亲的id,孩子数量,孩子id,以及房产和总资产。求出一共有多少个家庭,然后每行要输出每个家庭最小成员的id,总人数,平均房产以及平均总资产;按照平均总资产降序排列,如果有相同的则按照最小成员升序排列。
DFS查找连通图问题,也可以用并查集。设置孩子双亲数组保存每个人员的孩子和父母,注意这里要去重,每次输入数据的时候要双向保存。定义hash数组存放已经出现过得人员(应对单人家庭的情况)。

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <math.h>
#include <algorithm>
#define MAXN 10010
using namespace std;

struct family{
	int minmember,membernum;
	double avgsets,avgarea;
};
int sets[MAXN],area[MAXN];
vector<int> child[MAXN],parents[MAXN];
vector<family> fm;
int n;
bool visit[MAXN]={false},hashTable[MAXN];
void insert(vector<int> &a,int x){
	for(int i=0;i<a.size();i++){
		if(a[i]==x) return ;
	}
	a.push_back(x);
}
bool cmp(family a,family b){
	if(a.avgarea!=b.avgarea) return a.avgarea>b.avgarea;
	else return a.minmember<b.minmember;
}
void DFS(int index,int &minnumber,int &totalnum,int &totalsets,int &totalarea){
	visit[index]=true;
	totalarea+=area[index];
	totalsets+=sets[index];
	if(minnumber>index) minnumber=index;
	for(int i=0;i<parents[index].size();i++){
		if(!visit[parents[index][i]]){
			totalnum++;
			DFS(parents[index][i],minnumber,totalnum,totalsets,totalarea);
		}
	}
	for(int i=0;i<child[index].size();i++){
		if(!visit[child[index][i]]){
			totalnum++;
			DFS(child[index][i],minnumber,totalnum,totalsets,totalarea);
		}
	}
}
int main(){
	int id,fatherid,matherid,childid,childnum;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&id);
		scanf("%d%d",&fatherid,&matherid);
		hashTable[id]=true;
		if(fatherid!=-1){
			hashTable[fatherid]=true;
			insert(parents[id],fatherid);
			insert(child[fatherid],id);
		}
		if(matherid!=-1){
			hashTable[matherid]=true;
			insert(parents[id],matherid);
			insert(child[matherid],id);
		}
		scanf("%d",&childnum);
		for(int i=0;i<childnum;i++){
			scanf("%d",&childid);
			insert(child[id],childid);
			insert(parents[childid],id);
		}
		scanf("%d%d",&sets[id],&area[id]);
	}
	for(int i=0;i<MAXN;i++){
		if(!visit[i]&&hashTable[i]){
			int totalnum=1,totalarea=0,totalsets=0,minnumber=MAXN;
			DFS(i,minnumber,totalnum,totalsets,totalarea);
			family tmp;
			tmp.minmember=minnumber,tmp.membernum=totalnum,tmp.avgsets=totalsets*1.0/totalnum,tmp.avgarea=totalarea*1.0/totalnum;
			fm.push_back(tmp);
		}
	}
	sort(fm.begin(),fm.end(),cmp);
	printf("%d\n",fm.size());
	for(int i=0;i<fm.size();i++){
		printf("%04d %d %.3f %.3f\n",fm[i].minmember,fm[i].membernum,fm[i].avgsets,fm[i].avgarea);
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值