第27次CCF CSP(202209) T3非常详细题解 防疫大数据(C++)

-->原题链接

思路:

        大模拟最重要的是理清思路,针对该题的几块内容来说。

        对于地区:用map来存,用pair表示某个地区是风险区的连续的开始和结束时间。维护起来  也很简单。若日期为d的一天收到p地成为风险区的消息,就检查d是否在p是风险区的日期内,即p地在日期d是否为风险区,如果是,就把p地风险区的结束时间延长至d+6(取不到d+7)(如果p地是风险的连续日期为[a,b],那么d是b+1也是可以连起来的,40分可能是这里没处理好)。如果不是,就把p地的风险区的区间设为[d,d+6]。

        对于漫游消息:用结构体表示,用vector数组存,二维数组也可以。第d天收到的消息就存到下标为d的数组里面。

        处理结果:读入数据后。在存漫游消息的数组里遍历前六天到现在的所有漫游消息,对于遍历到的每条漫游消息都检查一下看是否满足条件,若满足就把这条消息里的人加入答案中。最后把答案排序去重输出就可以了。

代码(注释):

#include<bits/stdc++.h>
using namespace std;

int n,m,r;
struct Data{//漫游消息
    int d,u,p;
};
vector<Data> v[1010];//存漫游消息
map<int,pair<int,int> > pos; //每个地区的风险区持续时间
map<int,bool> st;//每个地区是否曾被设为风险区

void setf(int p,int d){//将p地设为风险区,日期是d
    if(!st[p]) pos[p]={d,d+6};
    else{
        if(d<=pos[p].second+1) pos[p].second=d+6;//可以连起来
        else pos[p]={d,d+6};
    }
    st[p]=true;
}

bool check(int d1,int u,int p,int d){//检查<d1,u,p>这条漫游消息是否满足条件,d为当前日期
    if(st[p]&&d1>=d-6&&d1<=d&&d1>=pos[p].first&&d<=pos[p].second) return true;
    return false;
}

int main(){
    cin>>n;
    for(int h=0;h<n;h++){//h表示当前日期
        cin>>r>>m;
        for(int i=1;i<=r;i++){//读入风险区并更新
            int t;
            cin>>t;
            setf(t,h);
        }
        for(int i=1;i<=m;i++){//读入漫游消息并存入
            int d,u,p;
            cin>>d>>u>>p;
            if(d<=h) v[h].push_back({d,u,p});
        }
        vector<int> ans;//当天的风险名单
        for(int i=(h-6>=0?h-6:0);i<=h;i++){//遍历漫游消息,满足的加入ans
            for(int j=0;j<v[i].size();j++){
                if(check(v[i][j].d,v[i][j].u,v[i][j].p,h)) ans.push_back(v[i][j].u);
            }
        }
        sort(ans.begin(),ans.end());
        ans.erase(unique(ans.begin(),ans.end()),ans.end());
        cout<<h;
        for(int i=0;i<ans.size();i++) cout<<" "<<ans[i];
        cout<<endl;
    }
    system("pause");
}

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值