题解:P7196 [CTSC2002] 灭鼠行动

· · 题解

前言

更好的阅读体验。
其实有很多地方出题人没讲清楚,所以只保证代码可以通过本题数据。

细节

struct mouse{ int sex, x, y, w, age, coma, breed, cnt; mouse(int sex, int x, int y, int w):sex(sex), x(x), y(y), w(w){age = coma = breed = cnt = 0;} mouse(){} }d; list<mouse>mice; list<mouse>::iterator it, it2; int mp[60][60], L, R, m, n, mtot, Max, dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; struct arm{int t, x, y, ty;}li[110]; int lir, lil = 1, vis[60][60]; void micebreed(mouse&a){ if(a.coma || a.age < 5 || a.breed)return; int sum = 0; loop(it2)if(it2->x == a.x && it2->y == a.y)sum++; if(sum != 2)return;//恰好两只 loop(it2)if(it2->sex != a.sex && it2->x == a.x && it2->y == a.y){//异性且在一个格子内 if(it2->age < 5 || it2->coma)return; return void(it2->breed = a.breed = 4); } } void micemove(mouse&a){//移动 if(a.coma)return void(a.coma--);//昏迷 if(++a.age, a.breed)return;//是否繁殖 int &w = a.w, &x = a.x, &y = a.y; if(mp[x][y] & w)x += dx[(int)log2(w)], y += dy[(int)log2(w)];//直行 else if((mp[x][y]&left(w))&&(mp[x][y]&right(w)))//岔路 w = (((++a.cnt) & 1) ? left(w) : right(w)); else if(mp[x][y] & left(w))w = left(w);//单边 else w = right(w);//单边或死路 } void usearm(arm&a){ switch(a.ty){ case 1://强力炸弹 FL(i, 0, 3)FL(j, 0, L){ int x1 = a.x + dx[i] j, y1 = a.y + dy[i] j; if(x1 < 1 || y1 < 1 || x1 > m || y1 > n)break; vis[x1][y1] = lil; if(!(mp[x1][y1] & (1 << i)))break; } break;

    case 2://神秘射线
    loop(it2)if((int)(pow(it2->x - a.x, 2) + pow(it2->y - a.y, 2)) <= R * R)it2->coma += 3;
    break;

    case 3:vis[a.x][a.y] = lil;//定时炸弹
    break;

    case 4:loop(it2)if(it2->x == a.x && it2->y == a.y)it2->sex ^= 1;//生物炸弹
}
if(a.ty & 1)
    for(it2 = mice.begin(); it2 != mice.end();)
        if(vis[it2->x][it2->y] == lil)mtot--, it2 = mice.erase(it2);
        else it2++;

} int32_t main(){ cin.tie(0)->sync_with_stdio(0); cin >> L >> R >> m >> n; FL(i, 1, m)FL(j, 1, n)cin >> mp[i][j]; cin >> mtot; FL(i, 1, mtot){ char c; cin >> d.x >> d.y >> c; d.w = ((c <= 'N') ? (c == 'E' ? E : N) : (c == 'S' ? S : W)); cin >> c, d.sex = (c == 'X'), d.age = 5, mice.push_back(d); } cin >> lir >> Max; FL(i, 1, lir)cin >> li[i].ty >> li[i].t >> li[i].x >> li[i].y, ((li[i].ty == 3) && (li[i].t += 3));//定时炸弹加上爆炸时间 sort(li + 1, li + 1 + lir, [](arm&i, arm&j){return i.t < j.t;});//暗时刻排序 int T; cin >> T; cheakover; FL(T, 0, T){ //使用武器 while(lil <= lir && li[lil].t == T)usearm(li[lil++]); //繁殖 loop(it)micebreed(it); loop(it){ if(it->coma || !it->breed)continue; if(((--it->breed) == 1) && it->sex) FL(j, 0, 3)if((mp[it->x][it->y] >> j & 1) && ++mtot) mice.emplace_back(j + 1 & 1, it->x, it->y, 1 << j); } cheakover; //移动 loop(it)micemove(it); if(!mtot)break; } cout << mtot; return 0; }