• 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]);
        }
    }
  • 相关阅读:
    怎样修改flash builder注释里的@author
    target与currentTarget的区别?
    java ByteBuffer flip()和limit()的理解
    flashplayer重绘机制
    Flex sdk4.6及flex Builder 4.6下载地址
    关闭MyEclipse Derby服务
    chrome浏览器设置debug版本的flashplayer
    C# MySql 整理
    windows下查看及修改DNS服务器
    eclipse引入第三方jar包
  • 原文地址:https://www.cnblogs.com/8023spz/p/7827725.html
Copyright © 2020-2023  润新知