L2-007 家庭房产 题解

L2-007 家庭房产:

思路:

1.因为要根据题给的隐藏关系划分家庭,所以并查集

2.合并操作的UNION函数做一些小小的变化,保证根结点是集合中数值最小的

3.记录每个人的房产数,房产总面积,并在最后加到大家庭(集合)的数据中

#include<cstdio>
#include<map>//使用到pair
#include<algorithm>//sort
using namespace std;
typedef pair<float,float> geren;//定义一个名为geren的floa对floa的数据类型
const int N=10010;//编号是四位数
//用于记录划家庭(集合)后每个家庭的情况
struct jiaxinxi{
    int hao;
    int ren=0;//后面记录大家庭人数时包括了根结点自己,所以此处为0
    float junnum=0;
    float juns=0;
}xinxi[N];
int n;
int father[N];
//本题中由题目给出出现的编号,并不是从1~n所有的数都出现,所以使用一个bool的数组记录出现的数字编号
bool isroot[N],chuxian[N]={false};
void init( ){
    for(int i=0;i<N;i++){
        father[i]=i;
        isroot[i]=false;
    }
}
int findfather(int x){
    while(x!=father[x]){
        x=father[x];
    }
    return x;
}
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;
    }
}
//结构体比较函数
bool cmp(jiaxinxi a,jiaxinxi b){
    if(a.juns!=b.juns) return a.juns>b.juns;//面积先大后小
    else return a.hao<b.hao;//编号先小后大
}
int main(){
    int i,j,numk,numj=0,ji,fu,mu,zi;
    geren zijixinxi[N];//用于记录每个人的房产数,房产总面积
    scanf("%d",&n);
    init();
    for(i=0;i<n;i++){
        //自己,父亲,母亲,儿子数量
        scanf("%d %d %d %d",&ji,&fu,&mu,&numk);
        chuxian[ji]=true;//标记编号出现
        if(fu!=-1){
            UNION(ji,fu);
            chuxian[fu]=true;
        }
        if(mu!=-1){
            UNION(ji,mu);
            chuxian[mu]=true;
        }
        for(j=0;j<numk;j++){
            scanf("%d",&zi);
            UNION(ji,zi);
            chuxian[zi]=true;
        }
        scanf("%f %f",&zijixinxi[ji].first,&zijixinxi[ji].second);
    }
    //对出现的编号,寻找他们的根结点并标记
    for(i=0;i<N;i++){
        if(chuxian[i]){
            isroot[findfather(i)]=true;
        }
    }
    //寻找根结点,记数并记录在大家庭情况的结构体数组中
    for(i=0;i<N;i++){
        if(chuxian[i]){
            if(isroot[i]){
                xinxi[numj++].hao=i;
            }
        }
    }
    for(i=0;i<N;i++){
        if(chuxian[i]){
            for(j=0;j<numj;j++){
                //如果当前编号是这个大家庭中的人
                if(findfather(i)==xinxi[j].hao){
                    xinxi[j].ren++;
                    xinxi[j].junnum+=zijixinxi[i].first;
                    xinxi[j].juns+=zijixinxi[i].second;
                    break;//集合间不会有交集,执行完直接跳出
                }
            }
        }
    }
    //计算平均值
    for(i=0;i<numj;i++){
        xinxi[i].junnum=xinxi[i].junnum/xinxi[i].ren;
        xinxi[i].juns=xinxi[i].juns/xinxi[i].ren;
    }
    //按题目要求排序
    sort(xinxi,xinxi+numj,cmp);
    //输出
    printf("%d\n",numj);
    for(i=0;i<numj;i++){
        printf("%04d %d %.3f %.3f\n",xinxi[i].hao,xinxi[i].ren,xinxi[i].junnum,xinxi[i].juns);
    }
}
全部评论

相关推荐

Ncsbbss:又想干活又想要工资,怎么什么好事都让你占了
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-06 03:40
已编辑
在秋招的小白菜很想养修勾:一眼 苍穹外卖+谷粒商城,项目换一换吧,可以找一些付费知识星球博主带带,避免烂大街。多投投大厂,背背八股,你这学历乱杀了,等实习经验到位,到时候大厂闭眼选
投递美团等公司8个岗位
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
今天 14:46
和女友两个人马上毕业,现在我在鹅实习995,周六日偶尔也去北京;她在北京金融007,经常忙到后半夜,周末也没啥休息机会两个人现在都不咋聊天了,一句话隔半小时甚至半天才回。&nbsp;她是个很优秀的妹子,工作也很努力,是值得学习一辈子的人。我在努力工作求转正,即便不行至少赚到了一段不错的实习经历。已经异地了半年,接下来可能还会持续是这个状态。我们都算是对方重要的人,只是感觉看上去不是很有未来的样子。希望牛友们给点的鼓励
梦旅奇缘:很难。异地首先就已经很难了,加上妹子是金融行业,忙碌高压,对情感需求很高,而且见惯纸醉金迷,你的很多优势在她那里可能就不算什么了。这种情况下,在她们那里遇到一个能及时照顾她的人,即使那人可能很多条件不如你,你也有可能被分手。 说白了,两个卷王就不太适合在一起。因为卷王最大的优势,在另一个卷王那里就不算优势了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务