家庭房产(并查集)

家庭房产   (25分)

给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。

输入格式:

输入第一行给出一个正整数NN\le 10001000),随后NN行,每行按下列格式给出一个人的房产:

编号 父 母 k 孩子1 ... 孩子k 房产套数 总面积

其中编号是每个人独有的一个4位数的编号;分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k0\le0k\le 55)是该人的子女的个数;孩子i是其子女的编号。

输出格式:

首先在第一行输出家庭个数(所有有亲属关系的人都属于同一个家庭)。随后按下列格式输出每个家庭的信息:

家庭成员的最小编号 家庭人口数 人均房产套数 人均房产面积

其中人均值要求保留小数点后3位。家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。

输入样例:

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

输出样例:

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

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>

using namespace std;
int n;

int fa[10005];
int vis[10005];
struct DATA
{
    int id;
    int fid;
    int mid;
    int k;
    int cid[10];
    int n;
    int s;
}d[1005];


void UFset()
{
    for(int i=0;i<=9999;i++)
    {
        fa[i]=i;
    }
}

int Find(int x)
{
    if(fa[x]==x)
    {
        return x;
    }
    else
    {
        return fa[x]=Find(fa[x]);
    }
}

void Union(int a,int b)
{
    if(a==b) return;
    int ia=Find(a);
    int ib=Find(b);
    if(ia<ib)
    {
        fa[ib]=ia;
    }
    else
    {
        fa[ia]=ib;
    }
}

struct ANS
{
    int id;
    int num;
    int n;
    int s;
}ans[10005];

struct RES
{
    int id;
    int num;
    double b1;
    double b2;
}res[10005];
int cnt;

int cmp(RES a,RES b)
{
    if(a.b2==b.b2)
    {
        return a.id<b.id;
    }
    return a.b2>b.b2;
}


int main()
{
    UFset();
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d",&d[i].id,&d[i].fid,&d[i].mid);
        vis[d[i].id]=1;
        if(d[i].fid!=-1)
        {
            vis[d[i].fid]=1;
            Union(d[i].id,d[i].fid);
        }
        if(d[i].mid!=-1)
        {
            vis[d[i].mid]=1;
            Union(d[i].id,d[i].mid);
        }
        scanf("%d",&d[i].k);
        for(int j=0;j<d[i].k;j++)
        {
            scanf("%d",&d[i].cid[j]);
            if(d[i].cid[j]!=-1)
            {
                vis[d[i].cid[j]]=1;
                Union(d[i].id,d[i].cid[j]);
            }
        }
        scanf("%d%d",&d[i].n,&d[i].s);
    }
    for(int i=0;i<10000;i++)
    {
        ans[i].id=-1;
    }
    for(int i=0;i<n;i++)
    {
        int ID=Find(d[i].id);
        ans[ID].id=ID;
        ans[ID].n+=d[i].n;  //统计房产总数
    //    ans[ID].num   //人口总数不能统计
        ans[ID].s+=d[i].s;
    }
    for(int i=0;i<10000;i++)  //统计家庭人口总数
    {
        if(vis[i]==1)
        {
            ans[Find(i)].num+=1;
        }
    }
    for(int i=0;i<10000;i++)
    {
        if(ans[i].id>=0)
        {
            res[cnt].id=ans[i].id;
            res[cnt].num=ans[i].num;
            res[cnt].b1=ans[i].n*1.0/ans[i].num;
            res[cnt].b2=ans[i].s*1.0/ans[i].num;
            cnt++;
        }
    }
    sort(res,res+cnt,cmp);
    printf("%d\n",cnt);
    for(int i=0;i<cnt;i++)
    {
        printf("%04d %d %.3f %.3f\n",res[i].id,res[i].num,res[i].b1,res[i].b2);
    }
    return 0;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,L2-007 家庭房产问题是关于家庭的房产和人口信息的处理。首先使用并查集的思维将数据存放至其中,并找到每个家庭最小的成员代表整个家庭。然后计算每个家庭的房产总和和家庭人口数量,并计算每个成员的个人房产。接着创建一个结构体 NODE2 存放清除无效数据后的数据,并按照题目要求进行排序。 具体实现中,可以使用find函数和Union函数来实现并查集的操作。find函数通过循环找到家庭的代表成员,Union函数用于合并两个家庭的代表成员。 最后,按照人均面积降序输出家庭信息,并按照成员编号的升序输出。人均值需要保留小数点后3位。 通过给定的示例输入和输出,我们可以看到处理结果的具体格式和要求。 希望以上信息能够帮助到您。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C语言:L2-007 家庭房产 (25 分) — 并查集](https://blog.csdn.net/WZRbeliever/article/details/122756645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [L2-007 家庭房产 (25 分)](https://blog.csdn.net/Hickey_Chen/article/details/83480139)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值