zoukankan      html  css  js  c++  java
  • 【刷题-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
    ", cnt);
        for(int i = 0; i < cnt; ++i){
            printf("%04d %d %.3f %.3f
    ", 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
    ", v2[i].id, v2[i].peoNum, v2[i].Sav / v2[i].peoNum, v2[i].Aav / v2[i].peoNum);
        }
        return 0;
    }
    
  • 相关阅读:
    互联网之用
    数据结构C语言>数组>一维数组表示二维数组
    关于启动Activity之间的及普通按钮的点击事件
    创建一个新的安卓应用程序 设置主Activity
    关于Activity之间传送数据
    Displaying a Tree control as a pop up for a Flex PopUpButton control (转载)
    Creating an undraggable Alert control in Flex (转载)
    Embedding external files using [Embed] (转载:学习如何嵌入外部文件)
    Creating unique identifiers for objects using the getUID() (转载)
    Adding animations and effects to Flex tool tips (转载)
  • 原文地址:https://www.cnblogs.com/vinnson/p/10845091.html
Copyright © 2011-2022 走看看