PAT甲级1114 Family Property (25分) 题不难,麻烦点 ,并查集变形, map 我是左箭头 int,node 我是右箭头 mapp

在这里插入图片描述
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,以及这个id的对应的父亲id 孩子id 以及estate和area
你需要根据给的信息把所有的有关的人归到一类之中

  1. 归类使用并查集,题目要求最小的id为一类的首领,只要在并查集合并函数时候判断一下id大小,pre[大的id]=小的[id]
  2. 然后得到了记录所有id的首领信息的pre数组,需要提取pre数组里面存了几个id的值,样例的pre里面就保存了8888 0001 5551 三个id的值,提取方法很多,可以使用一个sign【10000】数组,sign[pre[i]]=1; 然后遍历sign数组,看看哪些值为1,那么就知道了有几个家族首领了。我用的set,感觉代码会少点
  3. 提取到了所有家族首领的id还需要 一个结构体来保存首领的id(排序输出时候需要用到)对应对应家族的人数啊 estate和area啊 。我是用的map<id,node> mapp 实现的
    unordered_map<int,node> mapp;
    for(auto it=ShowSn.begin(); it!=ShowSn.end(); it++)
    {
        node p=node();
        p.id=*it;
        mapp[*it]= p;
    }
  1. 然后对所有的id进行扫描(我也是用的set存储的),看看是那个家族的,把该id有的estate和area加到家族结构体中
  2. 最后输出还需要用到sort,我用了个vector存储node。。。。感觉好麻烦。。。。

代码实现时候对于结构体,因为我们结构体是在map<int,node> 里面 和vector里面使用的,(不是之前二叉树时候结构体是被另一个结构体指针指向的,就需要new了),直接使用node a=node() 这种临时变量的形式就好了,不用new了,因为存储到map里面人家也会自己new一个新的结构体只是值和我们临时定义的结构体一样,地址啥的完全不一样了。
vector< int > 也是完全一样的,我们生命的结构体只是给人家传传值罢了

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
using namespace std;

int pre[10001];
int findP(int x)
{
    if(x!=pre[x])
        pre[x]=findP(pre[x]);

    return pre[x];
}
void Union(int a,int b)
{
    int ap=findP(a);
    int bp=findP(b);
    if(ap<bp)
        pre[bp]=ap;
    else
        pre[ap]=bp;
}
struct node
{
    int id;
    int num;
    double estate,area;
    node():num(0),estate(0),area(0) {}
};

int sort2(node a,node b){
    if(a.area!=b.area)
    return a.area>b.area;
    else{
         return a.id<b.id;
    }
}
int main()
{
    int N;
    cin>>N;
    double estateSn[10000]= {0};
    double areaSn[10000]= {0};

    for(int i=0; i<=9999; i++)
        pre[i]=i;

    unordered_set<int> idSet;


    for(int i=0; i<N; i++)
    {
        int id,idFather,idMother, childNum,estate,area;
        scanf("%d %d %d %d",&id,&idFather,&idMother,&childNum);

        idSet.insert(id);
        if(idFather!=-1)
        {
            idSet.insert(idFather);
            Union(id,idFather);
        }

        if(idMother!=-1)
        {
            idSet.insert(idMother);
            Union(id,idMother);
        }

        for(int q=0; q<childNum; q++)
        {
            int son;
            cin>>son;
            Union(id,son);
            idSet.insert(son);
        }
        cin>>estate>>area;
        areaSn[id]=area;
        estateSn[id]=estate;
    }
    unordered_set<int> ShowSn;
    for(auto it=idSet.begin(); it!=idSet.end(); it++)
        ShowSn.insert(findP(*it));
        
    unordered_map<int,node> mapp;
    for(auto it=ShowSn.begin(); it!=ShowSn.end(); it++)
    {
        node p=node();
        p.id=*it;
        mapp[*it]= p;
    }
    for(auto it=idSet.begin(); it!=idSet.end(); it++)
    {
        //这里记得用指针,结构体的等于是赋值,
        node *p=&mapp[pre[*it]];
        p->num++;
        p->area+=areaSn[*it];
        p->estate+=estateSn[*it];
    }
    vector<node> vec;
    for(auto it=mapp.begin(); it!=mapp.end(); it++){
        node *p=&it->second;
        p->estate=p->estate/p->num;

        p->area=p->area/p->num;
        vec.push_back(it->second);
    }

    sort(vec.begin(),vec.end(),sort2);
    cout<<vec.size()<<endl;
    for(int i=0;i<vec.size();i++){
        printf("%04d %d %.3f %.3f\n",vec[i].id,vec[i].num,vec[i].estate,vec[i].area);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值