CSP 202209-3 防疫大数据

有一个bug找了半年没找到,还是看别人博客才忽然意识到

[1,2,3,4]和[5,6,7,8]是可以合并的,脑子抽抽了没想到

整体流程还是比较暴力的

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
struct person{
    int d,u,r;
};
struct record{
    int  d0,d1,u,r;
};
unordered_map<int,set<pair<int,int>>> Areas;
unordered_map<int,vector<record>> Users;
set<int>dangerPeople;
bool isSafe(int day,int p) {//day日的名单、d0日收到的漫游数据、d1日到达r
    for(auto&ele : Users[p]) {
        int d0 = ele.d0;
        int r = ele.r;
        auto& area = Areas[r];
        if(area.empty()) continue;
        if(d0 < day - 6 || d0 > day) continue;
        if(ele.d1 < day - 6 || ele.d1 > day) continue;
        pair<int,int>range{ele.d1, day};
        for(auto& pr: area) {
            if(pr.first <= range.first && range.second <= pr.second) {
                return false;
            }
        }
    }
    return true;
}
void solveR(int day, int p){
    auto& area = Areas[p];
    if(area.empty()){area.insert({day, day + 6}); return;}
    auto edx = *area.rbegin();
    if(edx.second >= day || edx.second == day - 1) {
        int lx = min(edx.first, day);
        int rx = max(edx.second, day + 6);
        area.erase(edx);
        area.insert({lx,rx});
    } else {
        area.insert({day, day + 6});
    }
}
void solveM(int day,set<int>& res,person& p) {
    auto& area = Areas[p.r];
    if(area.empty()) {return;}
    if(p.d < day - 6){return;}
    pair<int,int> range{p.d, day};
    for(auto& rg:area) {
        if(rg.first <= range.first && rg.second >= range.second) {
            res.insert(p.u);
            return;
        }
    }
}
void solve(int day, int r, int m) {
    for(int i = 0; i < r; i++) {
        int p; cin >> p;
        solveR(day, p);
    }
    for(int i = 0; i < m; i++) {
        int dij,uij,rij;
        cin >> dij >> uij >> rij;
        person p = {dij,uij,rij};
        Users[uij].push_back({day,dij,uij,rij});
        solveM(day,dangerPeople,p);
    }
    set<int>safe;
    for(auto& per:dangerPeople) {
        if(isSafe(day,per)) safe.insert(per);
    }
    for(auto& per:safe) dangerPeople.erase(per);
    cout << day << ' ';
    for(auto per: dangerPeople) {

        cout << per << ' ';
    }
    cout << '\n';
}
int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    for(int day = 0; day < n; day++) {
        int r,m;
        cin >> r >> m;
        solve(day, r,m);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值