PAT 1114 Family Property

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 (≤). 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, -1 will be given instead); k (0) 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


思路为 使用并查集,确定每个家族中的最小ID,因为只有输入数据具有area set等信息,第一次遍历将房产信息归到 家族中最小ID的名下,顺便标记为是最小ID;

第二次遍历,将出现过的ID找到,给其对应的家族 的人数 加一; 同时记录有多少最小ID,即有多少个家族;

第三次遍历,将平均值设置好,压入vector中,最后排序
using namespace std;

int pre[10000];
struct node{
    int id,s,a;
};
int find(int x){
    return pre[x]==x?x:find(pre[x]);
}
void uni(int a,int b){
    int faa=find(a);
    int fab=find(b);
    if(faa>fab){
        pre[faa]=fab;
    }else{
        pre[fab]=faa;
    }
}
struct eva{
    int head,rs;
    double s,a,avs,ava;
    bool tou;
};
eva final[10004];
bool cmp1(eva a,eva b){
    if(a.ava!=b.ava){
        return a.ava>b.ava;
    }else{
        return a.head<b.head;
    }
}
bool visit[10000];
vector<node> arr;
int main() {
    //freopen("D://dio.txt","r",stdin);
    
    int n,id,fa,ma,k,kid,sets,area,i,j;    
    
    for(i=0;i<10000;i++){
        pre[i]=i;
    }
    cin>>n;
    int fn,ff,fm,fk;
    node temp;
    for(i=0;i<n;i++){
        scanf("%d %d %d %d",&id,&fa,&ma,&k);
        fn=find(id);
        if(fa!=-1){
            ff=find(fa);
            uni(fa,id);
            visit[fa]=true;
        }
        if(ma!=-1){
            fm=find(ma);
            uni(ma,id);
            visit[ma]=true;
        }
        visit[id]=true;
        for(j=0;j<k;j++){
            scanf("%d",&kid);
            fk=find(kid);
            uni(fk,fn);
            visit[kid]=true;
        }
        scanf("%d %d",&sets,&area);
        temp.id=id;
        temp.s=sets;
        temp.a=area;
        arr.push_back(temp);
    }
    for(i=0;i<arr.size();i++){
        int ii=find(arr[i].id);
    
        final[ii].head=ii;
        final[ii].s+=arr[i].s;
        final[ii].a+=arr[i].a;
        final[ii].tou=true;
    }
    int cnt=0;
    vector<eva> ginto;
    for(i=0;i<10000;i++){
        if(visit[i]){
        
            final[find(i)].rs++;
        }
        if(final[i].tou){
            cnt++;
            
        }
    }
    for(i=0;i<10000;i++){
        if(final[i].tou){
            final[i].avs=final[i].s/final[i].rs;
            final[i].ava=final[i].a/final[i].rs;
            ginto.push_back(final[i]);
        }
    }
    cout<<cnt<<endl;
    sort(ginto.begin(),ginto.end(),cmp1);
    for(i=0;i<ginto.size();i++){
        printf("%04d %d %.3f %.3f\n",ginto[i].head,ginto[i].rs,ginto[i].avs,ginto[i].ava);
    }
    return 0;
}
  
上一篇:1114 Family Property (25 point(s))


下一篇:信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1114:白细胞计数