2020 年百度之星·程序设计大赛 - 初赛二

Covid



Problem Description

科学家小沃沃在研究病毒传播的规律,从而控制疫情。有 n 个人,编号分别为 1,2,...,n。我们用荧光粉代替病毒,编号为 1 的人,在第 0 时刻涂上了荧光粉,剩下的人在第 0 时刻没有涂。
对于第 i 个人,我们知道这个人在哪些时刻出现在了哪些地方。
如果时刻 t,某个人和身体上有荧光粉的人,出现在了同一地点,那么从时刻 t 以后,这个人也会沾上荧光粉。
从小到大输出实验结束后身体上有荧光粉的人的编号。


Input

第一行一个整数 T(1≤T≤20)表示 T 组数据。对于每组数据,第一行一个整数 n(1≤n≤20000)表示 n 个人。 对于第 i 个人,第一行输入一个整数 len [i] (1≤len[i]≤100)表示这个人的活动轨迹。 接下来 len[i]行,每行输入两个整数 t,p(1≤t≤100,1≤p≤10)表示这个人t时刻出现在了p位置,保证t按严格递增的顺序给出。 除了这 len[i]个时刻,这个人都呆在家里,或者换句话说,他/她不在任何位置。 保证len[1]+len[2]+...+len[n]≤200000。


Output

对于每组数据输出一行,表示所有患者的编号。按编号从小到大输出。


样例输入

2
4
2
1 1
2 2
3
2 2
3 3
4 4
1
4 4
1
2 1
3
3
1 1
3 1
6 1
3
4 1
5 1
6 1
1
5 1


样例输出

1 2 3
1 2

我的思路呢,是在输入的时候,对数据进行一个预处理,将某一时刻在某一个位置的人进行分类,然后逐个时间逐个位置的去处理,如果某一时刻的某一个位置有得病的人,则将在这个时间,在这个位置的所有人全都标记一遍。

本人比赛时的AC代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        int a[n+10]={0,1};//记录某一号人是否得病
        vector<int>se[120][15];  //一个三维数组,来表示在某一时刻的某一位置有谁
        int maxx=0;
        for(int i=1;i<=n;i++){//i代表第几号人
            int m;
            scanf("%d",&m);
            /*预处理,将对应的人放在某一时刻的某一位置*/
            for(int j=1;j<=m;j++){	//j来表示出门次数
                int p,q;
                scanf("%d%d",&p,&q);	
                maxx=max(maxx,p);	//貌似没啥用
                se[p][q].push_back(i);	//将人放到对应的位置
            }
        }
        for(int i=1;i<=110;i++){
            for(int k=1;k<=10;k++){
                for(int j=0;j<se[i][k].size();j++){
                    if(a[se[i][k][j]]==1) {//看看在i时刻j位置的人是否有得病的,如果有则将此时刻在这个位置的所有人都标记一下
                        for(int p=0;p<se[i][k].size();p++){
                            a[se[i][k][p]]=1;
                        }
                        break;
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(a[i]){
            /*最后输出,貌似程序不卡这个格式的空格*/
                if(i==1)
                    printf("%d",i);
                else
                    printf(" %d",i);
            }
        }
        printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值