欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1003. Covid (思维 / 小根堆)(2020年百度之星*程序设计大赛-初赛二)

程序员文章站 2022-07-03 18:14:55
...

传送门

1003. Covid (思维 / 小根堆)(2020年百度之星*程序设计大赛-初赛二)
1003. Covid (思维 / 小根堆)(2020年百度之星*程序设计大赛-初赛二)
1003. Covid (思维 / 小根堆)(2020年百度之星*程序设计大赛-初赛二)
思路:

  • 比赛的时候想到用并查集,但发现变量很多不知道怎么实现,一直写不出。

  • 官方题解:1003. Covid (思维 / 小根堆)(2020年百度之星*程序设计大赛-初赛二)
    (小根堆的代码后期若写出再来补充!)

  • 看了wyh的代码才知道其实这个题很简单。直接用个三维数组,第一维记录时间,第二维记录地点,第三维当然就是记录人员编号了。

  • 然后以<时间,地点>为索引来处理,具体细节见代码。(比赛时我就傻傻的以人头为索引来处理,结果后面发现这样处理会不完全。)

代码实现:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;

inline void read(int &x){
    char t=getchar();
    while(!isdigit(t)) t=getchar();
    for(x=t^48,t=getchar();isdigit(t);t=getchar()) x=x*10+(t^48);
}

int T, n, vis[N];
vector<int> ans, mp[105][15];


int main()
{
    read(T);
    while(T --){
        read(n);
        //初始化数组
        for(int i=1;i<=100;i++)
            for(int j=1;j<=10;j++)
                mp[i][j].clear();
        //将对应的人员编号分配到相应的<时间,地点>元组里
        for(int i = 1; i <= n; i ++){
            int len; read(len);
            for(int j = 1; j <= len; j ++){
                int t, p; read(t); read(p);
                mp[t][p].push_back(i);
            }
        }
        vis[1] = 1; //先将1号人员标记已被感染
        for(int i = 1; i <= 100; i ++){
            for(int j = 1; j <= 10; j ++){
                int ok = 0;
                for(auto it : mp[i][j])
                    if(vis[it]){ok = 1; break;} //若发现该<时间,地点>有一人已被感染。
                if(ok) for(auto it : mp[i][j]) vis[it] = 1; //那么标记该<时间,地点>的人员都已被感染
            }
        }
        ans.clear();
        for(int i = 1; i <= n; i ++) //开始在所有人员中锁定被感染人员,并释放该位置的标号vis[i]
            if(vis[i]){ans.push_back(i); vis[i] = 0;}
        for(int i = 0; i < ans.size()-1; i ++) printf("%d ", ans[i]);
        printf("%d\n", ans.back());
    }

    return 0;
}