家庭房产

来源:互联网 发布:2016年2月非农数据 编辑:程序博客网 时间:2024/04/27 11:22
5-11 家庭房产   (25分)

给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。

输入格式:

输入第一行给出一个正整数NN\le 10001000),随后NN行,每行按下列格式给出一个人的房产:

编号 父 母 k 孩子1 ... 孩子k 房产套数 总面积

其中编号是每个人独有的一个4位数的编号;分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k0\le0k\le 55)是该人的子女的个数;孩子i是其子女的编号。

输出格式:

首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:

家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积

其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。

输入样例:

106666 5551 5552 1 7777 1 1001234 5678 9012 1 0002 2 3008888 -1 -1 0 1 10002468 0001 0004 1 2222 1 5007777 6666 -1 0 2 3003721 -1 -1 1 2333 2 1509012 -1 -1 3 1236 1235 1234 1 1001235 5678 9012 0 1 502222 1236 2468 2 6661 6662 1 3002333 -1 3721 3 6661 6662 6663 1 100

输出样例:

38888 1 1.000 1000.0000001 15 0.600 100.0005551 4 0.750 100.000
#include <cstdio>#include <vector>#include <queue>#include <cmath>#include <algorithm>#include <iostream>using namespace std;int house[10000],area[10000];int book[10000],has[10000];int head[10000],cnt;struct node{int to;int next;}edges[14005];struct nodes{int MinNumber;int count;double houses;double areas;};vector<struct nodes> v;void Add(int x,int y){cnt++;edges[cnt].to=y;edges[cnt].next=head[x];head[x]=cnt;}void bfs(int fa){int Min=fa,count=1,houses=house[fa],areas=area[fa];struct nodes temp;queue<int> q;q.push(fa);has[fa]=1;while(!q.empty()){int h=q.front();q.pop();for(int i=head[h];i;i=edges[i].next){int to=edges[i].to;if(book[to]&&!has[to]){q.push(to);has[to]=1;count++;houses+=house[to];areas+=area[to];Min=min(Min,to);}}    }    temp.MinNumber=Min;    temp.count=count;    temp.houses=(double)houses/count;    temp.areas=(double)areas/count;    v.push_back(temp);}bool cmp(nodes a,nodes b){if(fabs(a.areas-b.areas)>1e-6){return a.areas>b.areas;}else{return a.MinNumber<b.MinNumber; }}int main(){int n;int num,fa,ma,sons,son;cin>>n;for(int i=1;i<=n;i++){cin>>num;book[num]=1;cin>>fa;book[fa]=1;if(fa!=-1){Add(num,fa);Add(fa,num);}cin>>ma;book[ma]=1;if(ma!=-1){Add(num,ma);Add(ma,num);}cin>>sons;for(int i=1;i<=sons;i++){cin>>son;book[son]=1;Add(num,son);Add(son,num);}cin>>house[num]>>area[num];}for(int i=0;i<=9999;i++){if(book[i]&&!has[i]){bfs(i);}}sort(v.begin(),v.end(),cmp);cout<<v.size()<<endl; for(int i=0;i<v.size();i++){printf("%04d %d %.3f %.3f\n",v[i].MinNumber,v[i].count,v[i].houses,v[i].areas);}return 0;} 

法二:并查集
#include <cstdio>#include <iostream>#include <vector>#include <algorithm>using namespace std;int house[10000],area[10000],Min[10000],peop[10000],book[10000];int f[10000];struct node{int m,p;double aveh,avea;node(int a,int b,double c,double d):m(a),p(b),aveh(c),avea(d){}bool operator <(node b){if(fabs(this->avea-b.avea)>1e-6){return this->avea>b.avea;    }    else{    return this->m<b.m;    }}};int Get(int x){return f[x]=(f[x]==x?x:Get(f[x]));}void Init(){for(int i=0;i<10000;i++){Min[i]=i;f[i]=i;peop[i]=1;}}void Merge(int x,int y){int a=Get(x);int b=Get(y);if(a!=b){f[b]=a;}}int main(){int n;int num,fa,ma,k,son;vector<node> v;v.clear();cin>>n;Init();for(int i=1;i<=n;i++){cin>>num>>fa>>ma>>k;book[num]=1;if(fa!=-1){Merge(num,fa);book[fa]=1;}if(ma!=-1){Merge(num,ma);book[ma]=1;}for(int j=1;j<=k;j++){cin>>son;Merge(num,son);book[son]=1;}cin>>house[num]>>area[num];}for(int i=0;i<10000;i++){if(!book[i]){continue;}fa=Get(i);if(i!=fa){house[fa]+=house[i];area[fa]+=area[i];Min[fa]=min(Min[fa],i);peop[fa]+=peop[i];}}for(int i=0;i<10000;i++){if(book[i]&&f[i]==i){v.push_back(node(Min[i],peop[i],(double)house[i]/peop[i],(double)area[i]/peop[i]));}}cout<<v.size()<<endl;sort(v.begin(),v.end());for(unsigned int i=0;i<v.size();i++){printf("%04d %d %.3f %.3f\n",v[i].m,v[i].p,v[i].aveh,v[i].avea);}return 0;}
1 0
原创粉丝点击