题解:CF1970F3 Playing Quidditch (Hard)

· · 题解

题意简述

有红蓝两队玩寇地奇。队员分别为 R0,R1,...,R9B0,B1,...,B9 (有些队员可以不出现)。场地为一个 N \times M 的长方形。场地上除了有队员以外还有:

每一个时刻 0 \le t<T,给定一个单位(队员或者游走球),有以下事件:

在球被队员抓住时,球会跟着队员移动。

程序要按照 t 从小到大依次输出以下类型的事件:

在最后,输出红蓝两队的得分。

以上内容仅为题意简述,更多条件见原题面。

题解

大模拟的实际难度应该是显示的难度降两档才对。

直接按题意模拟事件。我们需要处理:

枚举每一时刻,我们可以先根据发生的事件简单处理坐标更新、球被抓住的状态更新。然后再依次处理每个事件。发生的事件处理如下:

然后依次处理要求输出的每个事件:

代码基本是按照上述流程走的。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int p,n,m,T;
int scorer,scoreb;
pair<int,int> pos[31];
int gtype[101][101];//=0没有球门,=1红球门,=2蓝球门
vector<int> alive,nxt,elim;
/*
-21 红球门
-11 蓝球门
-1 floor
00-09 R0-R9 
10-19 B0-B9 
21 Quaffle
22 Bludger
23 Golden Snitch
*/
int catching=-1;
int toid(string s){
    if(s=="RG") return -21;
    if(s=="BG") return -11;
    if(s==".Q") return 21;
    if(s==".B") return 22;
    if(s==".S") return 23;
    if(s=="..") return -1;
    if(s[0]=='R')   return s[1]-'0';
    else    return s[1]-'0'+10;
}
string tostr(int id){
    if(id==-1)  return "NONE";
    if(id<10)   return string("R")+char(id%10+'0');
    else    return string("B")+char(id%10+'0');
}
string tmp;
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin >> tmp;
            int id=toid(tmp);
            if(id>=0){
                pos[id]=make_pair(i,j);
            } else if(id==-21){
                gtype[i][j]=1;
            } else if(id==-11){
                gtype[i][j]=2;
            }
            if(0<=id && id<20){
                alive.push_back(id);
            }
        }
    }
    sort(alive.begin(),alive.end(),[](int x,int y){return tostr(x)<tostr(y);});
    cin >> T;
    for(int t=0;t<T;t++){
        cin >> tmp;
        char op;
        cin >> op;
        int id=toid(tmp),id2=-1;
        if(op=='U'){
            pos[id].first--;
        } else if(op=='D'){
            pos[id].first++;
        } else if(op=='L'){
            pos[id].second--;
        } else if(op=='R'){
            pos[id].second++;
        } else if(op=='T'){
            catching=-1;
        } else if(op=='C'){
            cin >> tmp;
            id2=toid(tmp);
            if(id2==21){
                catching=id;
            }
        }
        if(catching!=-1){
            pos[21]=pos[catching];
        } else{
            int gt=gtype[pos[21].first][pos[21].second];
//          cout << "[debug] Quaffle pos=(" << pos[21].first << ", " << pos[21].second << ").\n";
            if(gt==1){
                cout << t << " BLUE GOAL\n";
                ++scoreb;
            } else if(gt==2){
                cout << t << " RED GOAL\n";
                ++scorer;
            }
            pos[21]=make_pair((n+1)/2,(m+1)/2);
        }
        nxt.clear();
        elim.clear();
        for(auto &i:alive){
            if(pos[i]==pos[22]){
                elim.push_back(i);
                if(catching==i){
                    catching=-1;
                }
                continue;
            }
            nxt.push_back(i);
        }
        swap(nxt,alive);
        for(auto &i:elim){
            cout << t << ' ' << tostr(i) << " ELIMINATED\n";
        }
        int cgs=0;
        if(op=='C' && id2==23){
            if(id<10){
                cgs=1;
            } else{
                cgs=2;
            }
        }
        if(cgs==1){
            cout << t << " RED CATCH GOLDEN SNITCH\n";
            scorer+=10;
            goto ed;
        } else if(cgs==2){
            cout << t << " BLUE CATCH GOLDEN SNITCH\n";
            scoreb+=10;
            goto ed;
        }

//      cout << "[debug]at t=" << t << ", now catching=" << tostr(catching) << ", pos R0=(" << pos[0].first << ", " << pos[0].second << "), pos B0=(" << pos[10].first << ", " << pos[10].second << ").\n";
//      cout << "[debug]pos Bludger=(" << pos[22].first << ", " << pos[22].second << ").\n";
    }
    ed:;
    cout << "FINAL SCORE: " << scorer << ' ' << scoreb;
    return 0;
}

tips