L2-007. 家庭房产

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

输入格式:

输入第一行给出一个正整数N(<=1000),随后N行,每行按下列格式给出一个人的房产:

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

其中 编号 是每个人独有的一个4位数的编号; 分别是该编号对应的这个人的父母的编号(如果已经过世,则显示-1);k(0<=k<=5)是该人的子女的个数;孩子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

简单并查集题目,就是看看一共有几个家族,设一个vis数组,访问过的全部标记为一,那么有亲子关系的就并到一起,f数组是并查集中记录每个点的父亲。
数据读取完了,把整个id范围读一遍,如果id和父亲点的id相同那么就记录他的地址。排个序,输出。

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std ;
#define MAX 10000///最大范围
int f[MAX],vis[MAX]={0};///f用于记录并查集每个点的父亲 vis记录是否访问过
struct family///家族结构体
{
    int id,people ;
    double area,house ;//area是占地面积  house是房产套数
};
family person[MAX],*ans[MAX];//person记录相应id的家族信息,ans是个指针数组,记录答案
int ant = 0;//ans数组下标
bool cmp(family *a,family *b)///排序比较函数
{
    if((a->area / a->people) == (b->area / b->people))
        return a->id < b->id;
    return (a->area / a->people) > (b->area / b->people);
}
void init()///初始化f
{
    for(int i = 0;i < MAX;i ++)
        f[i] = i;
}
int getf(int x)///get father
{
    if(x != f[x])f[x] = getf(f[x]);
    return f[x];
}
void marriage(int x , int y)///merge合并
{
    int xx,yy;
    xx = getf(x) ;
    yy = getf(y) ;
    if(xx != yy)
    {
        if(xx > yy)///方便找到最小id  让id小的当父亲那么找到的id与父亲相等的点最小id就是自己
        {
            f[xx] = yy;
        }
        else f[yy] = xx;
    }
}

int main()
{
    int n,id,mother,father,k,child;
    cin>>n;
    init();
    for(int i = 0;i < n;i ++)
    {
        cin>>id>>father>>mother;
        vis[id] = 1 ;
        if(mother!=-1) {marriage(id,mother);vis[mother]=1;}///假如父亲访问过那么他肯定已经和id合并过 母亲也是
        if(father!=-1) {marriage(id,father);vis[father]=1;}
        cin>>k;
        for(int j = 0;j < k;j ++)
        {
            cin>>child;
            if(child!=-1)
            {
                marriage(id,child);
                vis[child] = 1;
            }
        }
        cin>>person[id].house>>person[id].area;///id作为下标方便寻找
    }
    for(int i = 0;i < MAX;i ++)
    {
        if(!vis[i])continue;
        int f = getf(i);
        if(f == i)
        {
            person[i].people ++;
            ans[ant ++] = &person[i];
            person[i].id = i;///需要注明
            continue;
        }
        person[f].people ++;
        person[f].house += person[i].house;
        person[f].area += person[i].area;
    }
    sort(ans,ans + ant,cmp);
    cout<<ant<<endl;
    for(int i = 0;i < ant;i ++)
        printf("%04d %d %.3f %.3f
",ans[i]->id,ans[i]->people,ans[i]->house/ans[i]->people,ans[i]->area/ans[i]->people);
    return 0 ;
}

 备赛重温:

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

using namespace std;
int n;
int f[10000],pnum[10000];
set<int> s;
int id,fa,mo,k,child;
double fn,fc,fnum[10000],fcover[10000];
void init() {
    for(int i = 0;i < 10000;i ++) {
        f[i] = i;
        pnum[i] = 1;
    }
}
int getf(int x) {
    return x == f[x] ? x : f[x] = getf(f[x]);
}
int mer_(int x,int y) {
    int xx = getf(x),yy = getf(y);
    if(xx != yy) {
        if(xx < yy) swap(xx,yy);
        pnum[yy] += pnum[xx];
        fnum[yy] += fnum[xx];
        fcover[yy] += fcover[xx];
        f[xx] = yy;
    }
    return yy;
}
bool cmp(int a,int b) {
    if(fcover[a] == fcover[b]) return a < b;
    return fcover[a] > fcover[b];
}
int main() {
    cin >> n;
    vector<int> ans;
    init();
    for(int i = 0;i < n;i ++) {
        cin >> id >> fa >> mo >> k;
        s.insert(id);
        if(fa != -1) {
            s.insert(fa);
            id = mer_(id,fa);
        }
        if(mo != -1) {
            s.insert(mo);
            id = mer_(id,mo);
        }
        for(int j = 0;j < k;j ++) {
            cin >> child;
            s.insert(child);
            id = mer_(id,child);
        }
        cin >> fn >> fc;
        fnum[id] += fn;
        fcover[id] += fc;
    }
    for(set<int>::iterator it = s.begin();it != s.end();it ++) {
        if(f[*it] == *it) {
            fnum[*it] /= pnum[*it];
            fcover[*it] /= pnum[*it];
            ans.push_back(*it);
        }
    }
    sort(ans.begin(),ans.end(),cmp);
    cout << ans.size() << endl;
    for(vector<int>::iterator it = ans.begin();it != ans.end();it ++) {
        printf("%04d %d %.3f %.3f
",*it,pnum[*it],fnum[*it],fcover[*it]);
    }
}
原文地址:https://www.cnblogs.com/8023spz/p/7827725.html