[PTA] family property

Keywords: iOS

Topic restatement

Given each person's family members and the real estate under their own name, please count the population of each family, the per capita real estate area and the number of real estate units.

Input format:

Enter the first line to give a positive integer n (< 1000), followed by N lines, each line giving a person's property in the following format:

Number parent k child 1 Children k total area of real estate units

Among them, the number is a 4-digit number unique to each person; the parent and parent are the number of the parent of the person corresponding to the number (if they have passed away, display - 1); k (0 ≤ k ≤ 5) is the number of children of the person; child i is the number of children.

Output format:

First, output the number of families in the first line (all related people belong to the same family). Then output information for each family in the following format:

Minimum number of family members number of family population number of real estate units per capita area of real estate per capita

The per capita value shall be 3 decimal places. Family information is first output in descending order of per capita area, and if there is parallel, it is output in ascending order of member number.

Input example:

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

Output example:

3
8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

Title Solution

Using concurrent query set, put all members of a family into a set, and finally find the relevant information of the set.

If you don't know and check the collection, this blog post is good: Union checking set
This article refers to the ideas [patl2-007] family property

There are detailed comments in the code, hope to help you

C++ AC

#include <iostream>
#include <bits/stdc++.h>
#define MAX 10010
using namespace std;
struct person//Structure used to save input samples
{
    int id;//number
    int f_id;//Father's number
    int m_id;//Mother's number
    int k;//Number of children
    int child[10];//Save child's array
    int house_num;//House number
    int sum_area;//total area
};
struct rs//Structure used to output results -- family collection
{
    int id;//Minimum number
    int person_num;//Family size
    double ave_house;//Average number of properties
    double ave_area;//Average real estate area
};
int p[MAX];//Used to save superior
bool vis[MAX];//It is used to save the number. Because we use the method of typing table, we need to see which number is valid


bool cmp(rs x,rs y)//Custom structure comparison
{
    if(x.ave_area==y.ave_area)
    {
        return x.id<y.id;
    }

    else
    {
        return x.ave_area>y.ave_area;
    }

}
int find1(int x)//And look for the top leaders
{
    if(x==p[x])
    {
        return x;
    }
    else
    {
        return p[x]=find1(p[x]);
    }
}
void unite(int x,int y)//Consolidation of consolidation
{
    x=find1(x);
    y=find1(y);
    if(x==y)
        return;
    else
    {
        p[x]=y;
    }

}
int main()
{
    ios::sync_with_stdio(false);
    memset(vis,0,sizeof(vis));

    person ps[10005];//Use to save input samples
    rs result[10005];//Use to save output samples
    for(int i=0; i<10005; i++)
    {
        p[i]=i;//Default your superior is yourself
    }
    int n;
    cin>>n;

    for(int i=0; i<n; i++)
    {
        cin>>ps[i].id>>ps[i].f_id>>ps[i].m_id>>ps[i].k;
        vis[ps[i].id]=true;//Set the number to be valid
        if(ps[i].f_id!=-1)
        {
            unite(ps[i].id,ps[i].f_id);//Merge number and father's number
            vis[ps[i].f_id]=true;//Setting the number of the father is also valid
        }
        if(ps[i].m_id!=-1)
        {
            unite(ps[i].id,ps[i].m_id);//Mother's number
            vis[ps[i].m_id]=true;//Setting the number of the father is also valid
        }

        for(int j=0; j<ps[i].k; j++)
        {
            cin>>ps[i].child[j];
            unite(ps[i].id,ps[i].child[j]);//Put all the children's numbers in this collection
            vis[ps[i].child[j]]=true;//The child's number is also valid

        }
        cin>>ps[i].house_num>>ps[i].sum_area;
    }


    for(int i=0; i<n; i++)
    {
        int id=find1(ps[i].id);//Looking for the top
        result[id].ave_house+=ps[i].house_num;//The number of property units with the current number added to the top level
        result[id].ave_area+=ps[i].sum_area;//Total area of the highest level plus the current number
    }
    //It's used to record whether it's the superior or not
    bool record[100010];
    memset(record,0,sizeof(record));
    int k=0;
    for(int i=0; i<=9999; i++)
    {
        if(vis[i])
        {
            int t=find1(i);
            record[t]=true;

            if(!result[t].person_num)//Ensure that the id in the output result is the minimum id in the family
            {
                result[t].id=i;
            }
            result[t].person_num++;
        }
    }
    for(int i=0; i<10010; i++)
    {
        if(record[i])
        {
            result[i].ave_area=result[i].ave_area*1.0/result[i].person_num;
            result[i].ave_house= result[i].ave_house*1.0/result[i].person_num;
        }

    }
    //Sort the structure
    sort(result,result+10000,cmp);
    int ans=0;
    for(int i=0; i<10000; i++)
    {
        if(result[i].person_num)
        {
            ans++;
        }
    }
    printf("%d\n",ans);
    for(int i=0; i<ans; i++)
    {
        if(result[i].person_num)
        {
            printf("%04d %d %.3f %.3f\n",result[i].id,result[i].person_num,result[i].ave_house,result[i].ave_area);
        }
    }
    return 0;
}

Published 213 original articles, won praise 101, visited 40000+
Private letter follow

Posted by mark123 on Wed, 29 Jan 2020 22:13:58 -0800