【PAT甲级A1114】 Family Property (25分)(c++)

1114 Family Property (25分)

作者:CHEN, Yue
单位:浙江大学
代码长度限制:16 KB
时间限制:200 ms
内存限制:64 MB

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 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≤k≤5) 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升序。

思路:

用set记录总共有哪些人,用并查集分出家庭,其中根据题意要将小值作为父亲,然后在这些人中将同为一个父亲的点的房产和房产面积累加给父亲,再用一个set保存家庭,排序输出。

参考代码:

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;
const int maxn = 10000;
struct family {
    int id, num, estate, area;
    double totalestate, totaltarea, avge, avga;
} f[maxn];

bool cmp(family a, family b) {
    if (a.avga != b.avga)return a.avga > b.avga;
    else return a.id < b.id;
}

int father[maxn];

int findfather(int v) {
    if (father[v] == v)return v;
    else {
        int F = findfather(father[v]);
        father[v] = F;
        return F;
    }
}

void Union(int a, int b) {
    int fa = findfather(a);
    int fb = findfather(b);
    if (fa != fb) {
        if (fa < fb)father[fb] = fa;
        else father[fa] = fb;
    }
}

void init() {
    for (int i = 0; i < maxn; i++)
        father[i] = i;
}

int main() {
    init();
    int n, id, fa, mo, k, ch, es, ar;
    set<int> st, fst;
    vector<family> families;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d%d", &id, &fa, &mo, &k);
        f[id].id = id;
        st.insert(id);
        if (fa != -1) {
            Union(id, fa);
            f[fa].id = fa;
            st.insert(fa);
        }
        if (mo != -1) {
            Union(id, mo);
            f[mo].id = mo;
            st.insert(mo);
        }
        for (int j = 0; j < k; j++) {
            scanf("%d", &ch);
            Union(id, ch);
            st.insert(ch);
            f[ch].id = ch;
        }
        scanf("%d%d", &f[id].estate, &f[id].area);
    }
    for (auto it = st.begin(); it != st.end(); it++) {
        int index = findfather(*it);
        f[index].num++;
        f[index].totalestate += f[*it].estate;
        f[index].totaltarea += f[*it].area;
        fst.insert(index);
    }
    printf("%d\n", fst.size());
    for (auto it = fst.begin(); it != fst.end(); it++) {
        f[*it].avge = f[*it].totalestate / f[*it].num;
        f[*it].avga = f[*it].totaltarea / f[*it].num;
        families.push_back(f[*it]);
    }
    sort(families.begin(), families.end(), cmp);
    for (int i = 0; i < families.size(); i++) {
        printf("%04d %d %.3f %.3f\n", families[i].id, families[i].num, families[i].avge, families[i].avga);
    }
    return 0;
}

如有错误,欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值