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 NNN (≤1000\le 1000≤1000). Then NNN lines follow, each gives the infomation of a person who owns estate in the format:
ID
Father
Mother
kkk Child1⋯ChildkChild_1 \cdots Child_kChild1⋯Childk MestateM_{estate}Mestate 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); kkk (0≤k≤50\le k\le 50≤k≤5) is the number of children of this person; ChildiChild_iChildi's are the ID
's of his/her children; MestateM_{estate}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
AVGsetsAVG_{sets}AVGsets AVGareaAVG_{area}AVGarea
where ID
is the smallest ID in the family; M
is the total number of family members; AVGsetsAVG_{sets}AVGsets is the average number of sets of their real estate; and AVGareaAVG_{area}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
解题方法:采用结构体来存储人的编号,家族人的数量,以及mestata和area;
在输入每一行时,父母与孩子的编号,如果没有访问过,则置一个结构体,否则,不进行更改,有可能他们已经作为第一个结点出现过,更改会影响mestata以及area的数值
同时,注意编号是4位的编号,应包括0在内,我一开始在最后找有几个家族遍历所有成员的时候是从1开始的,导致三个样例过不了,更改为0后通过全部样例,同时应该注意平时在写数组的时候注意不要越界,上越界以及下越界都会导致程序出错
满分代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int vst[N];
set<int>st;
struct person{
int id,sum=0;
double mestate=0,area=0;
person(){};
person(int idd,int ssum,double mm,double aa){
id=idd;
sum=ssum;
mestate=mm;
area=aa;
}
bool operator < (const person &p)const{
if(area!=p.area)
return area>p.area;
return id<p.id;
}
}ps[N];
int n;
int fa[N];
//并查集
void init(){//初始化父节点
for(int i=1;i<=N;i++){
fa[i]=i;
}
}
int get(int x){//寻找父节点
if(fa[x]==x)
return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y){
//合并
x=get(x);
y=get(y);
if(x!=y){
fa[max(x,y)]=min(x,y);//父节点为较小的结点
}
}
bool same(int x,int y){
return get(x)==get(y);
}
int main(){
init();
cin>>n;
fill(vst,vst+N,0);
for(int i=1;i<=n;i++){
int id,fid,mid,num,child[8];
double mestate,area;
cin>>id>>fid>>mid>>num;
if(!vst[fid]&&fid!=-1){
ps[fid]=person(fid,0,0,0);
vst[fid]=1;
}
if(!vst[mid]&&mid!=-1){
ps[mid]=person(mid,0,0,0);
vst[mid]=1;
}
vst[id]=1;
if(fid!=-1&&!same(id,fid)){//合并一家人的结点
merge(id,fid);
}
if(mid!=-1&&!same(id,mid)){
merge(id,mid);
}
for(int i=1;i<=num;i++){
cin>>child[i];
if(!vst[child[i]])
ps[child[i]]=person(child[i],0,0,0);
vst[child[i]]=1;
if(!same(id,child[i])){
merge(id,child[i]);
}
}
cin>>mestate>>area;
ps[id]=person(id,0,mestate,area);
}
for(int i=0;i<=N;i++){
if(!vst[i]) continue;
if(get(i)==i){
ps[i].sum++;
st.insert(i);
continue;
}else{
int x=get(i);
st.insert(x);
ps[x].sum++;
ps[x].mestate+=ps[i].mestate;
ps[x].area+=ps[i].area;
}
}
cout<<st.size()<<endl;
person pe[st.size()+3];
int jj=0;
for(auto i=st.begin();i!=st.end();i++){
pe[jj]=ps[*i];
pe[jj].area=pe[jj].area/pe[jj].sum;
jj++;
}
sort(pe,pe+st.size());
for(int i=0;i<st.size();i++){
printf("%04d %d %.3f %.3f\n",pe[i].id,pe[i].sum,pe[i].mestate/pe[i].sum,pe[i].area);
}
return 0;
}