题解:P5506 封锁 / ARIS0_0 - 9

· · 题解

前言

是不是一车题解被 hack 了,补一个。

话说数据确实很水,现在还是很水。

思路

首先,这题的难点在于读题。

读完题发现其实重头戏在于移动,子弹,激光。

这里先把其他的讲一下,重头戏一会儿细说。

对于每一个无人机,你维护一个结构体。

struct plane{
    int x, y, z, h, f, atk, def, mat, mdf, hp, fix;
} a[N];

含义如题。

对于 FLRUD,直接按照题意改变即可。

void right(plane &t){
    t.f = (t.f + 7) % 8;
}
void left(plane &t){
    t.f = (t.f + 1) % 8;
}
void up(plane &t){
    if (t.h + 1 <= 4) t.h ++;
}
void down(plane &t){
    if (t.h - 1 >= 0) t.h --;
}
void fix(plane &t){
    t.hp += t.fix;
}

接下来开始描述别的。

移动

移动这个除了烦没别的,耐住性子对着题目的图片模拟去吧。

一个奇技淫巧:可以把题目中那一张对照表截图然后钉在桌面上,然后写一行盖一行(如果没有这个功能就算了)。

具体可以参照我的下面代码。

:::success[为什么用折叠框呢。]

void move(plane &t){
    int f = t.f, h = t.h;
    if (f == 0){
        if (h == 0) t.z --;
        if (h == 1) t.x ++, t.z --;
        if (h == 2) t.x ++;
        if (h == 3) t.x ++, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 1){
        if (h == 0) t.z --;
        if (h == 1) t.x ++, t.y ++, t.z --;
        if (h == 2) t.x ++, t.y ++;
        if (h == 3) t.x ++, t.y ++, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 2){
        if (h == 0) t.z --;
        if (h == 1) t.y ++, t.z --;
        if (h == 2) t.y ++;
        if (h == 3) t.y ++, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 3){
        if (h == 0) t.z --;
        if (h == 1) t.x --, t.y ++, t.z --;
        if (h == 2) t.x --, t.y ++;
        if (h == 3) t.x --, t.y ++, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 4){
        if (h == 0) t.z --;
        if (h == 1) t.x --, t.z --;
        if (h == 2) t.x --;
        if (h == 3) t.x --, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 5){
        if (h == 0) t.z --;
        if (h == 1) t.x --, t.y --, t.z --;
        if (h == 2) t.x --, t.y --;
        if (h == 3) t.x --, t.y --, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 6){
        if (h == 0) t.z --;
        if (h == 1) t.y --, t.z --;
        if (h == 2) t.y --;
        if (h == 3) t.y --, t.z ++;
        if (h == 4) t.z ++;
    }
    if (f == 7){
        if (h == 0) t.z --;
        if (h == 1) t.x ++, t.y --, t.z --;
        if (h == 2) t.x ++, t.y --;
        if (h == 3) t.x ++, t.y --, t.z ++;
        if (h == 4) t.z ++;
    }
}

:::

子弹

这里有一个比较坑的东西,就是你的索敌可以在自己想通位置上的其他飞碟,但是不会造成伤害。具体可以参见样例 2 的解释部分的一个链接。

那么回到正题,我们如何处理子弹。

考虑使用 map 记下每一个位置有哪些点,然后对于子弹,直接不断移动,知道移动出了边界(注:此处边界为 200 = 100 + 100)。

但凡找到一个点,上面有飞机,你就考虑这个点上的编号最小的,不是自己的飞机,然后如果能造成伤害就造成伤害。

激光

激光和子弹类似,但是不是找到第一个,而是找到所有的。

至此完结。

code

你们别不信,代码真不长,就 170 行左右吧。

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

#define int long long
#define pii pair<int, int>
#define piii pair<pii, int>
#define fi first
#define se second
const int N = 105;

namespace ARIS0_0{
    int n, t;
    struct plane{
        int x, y, z, h, f, atk, def, mat, mdf, hp, fix;
    } a[N];
    bool kil[N];
    string op[N];

    void init(){
    }
    void move(plane &t){
        int f = t.f, h = t.h;
        if (f == 0){
            if (h == 0) t.z --;
            if (h == 1) t.x ++, t.z --;
            if (h == 2) t.x ++;
            if (h == 3) t.x ++, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 1){
            if (h == 0) t.z --;
            if (h == 1) t.x ++, t.y ++, t.z --;
            if (h == 2) t.x ++, t.y ++;
            if (h == 3) t.x ++, t.y ++, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 2){
            if (h == 0) t.z --;
            if (h == 1) t.y ++, t.z --;
            if (h == 2) t.y ++;
            if (h == 3) t.y ++, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 3){
            if (h == 0) t.z --;
            if (h == 1) t.x --, t.y ++, t.z --;
            if (h == 2) t.x --, t.y ++;
            if (h == 3) t.x --, t.y ++, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 4){
            if (h == 0) t.z --;
            if (h == 1) t.x --, t.z --;
            if (h == 2) t.x --;
            if (h == 3) t.x --, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 5){
            if (h == 0) t.z --;
            if (h == 1) t.x --, t.y --, t.z --;
            if (h == 2) t.x --, t.y --;
            if (h == 3) t.x --, t.y --, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 6){
            if (h == 0) t.z --;
            if (h == 1) t.y --, t.z --;
            if (h == 2) t.y --;
            if (h == 3) t.y --, t.z ++;
            if (h == 4) t.z ++;
        }
        if (f == 7){
            if (h == 0) t.z --;
            if (h == 1) t.x ++, t.y --, t.z --;
            if (h == 2) t.x ++, t.y --;
            if (h == 3) t.x ++, t.y --, t.z ++;
            if (h == 4) t.z ++;
        }
    }
    void right(plane &t){
        t.f = (t.f + 7) % 8;
    }
    void left(plane &t){
        t.f = (t.f + 1) % 8;
    }
    void up(plane &t){
        if (t.h + 1 <= 4) t.h ++;
    }
    void down(plane &t){
        if (t.h - 1 >= 0) t.h --;
    }
    void fix(plane &t){
        t.hp += t.fix;
    }
    bool samepos(plane a, plane b){
        return (a.x == b.x && a.y == b.y && a.z == b.z);
    }
    bool ok(plane a){
        return (abs(a.x) <= 200 && abs(a.y) <= 200 && abs(a.z) <= 200);
    }
    void solve(){
        cin >> n >> t;
        for (int i = 1; i <= n; i ++ )
            cin >> a[i].x >> a[i].y >> a[i].z >> a[i].h >> a[i].f >> a[i].atk >> a[i].def >> a[i].mat >> a[i].mdf >> a[i].hp >> a[i].fix >> op[i];
        for (int i = 1; i <= n; i ++ )
            if (a[i].hp <= 0)
                kil[i] = 1;
        for (int tim = 0; tim < t; tim ++ ){
            for (int i = 1; i <= n; i ++ )
                if (!kil[i]) move(a[i]);
            map <piii, vector<int>> mp;
            for (int i = 1; i <= n; i ++ )
                if (!kil[i])
                    mp[{{a[i].x, a[i].y}, a[i].z}].push_back(i);
            for (int i = 1; i <= n; i ++ ){
                if (kil[i]) continue;
                char qqq = op[i][tim];
                if (qqq == 'N') continue;
                if (qqq == 'U') up(a[i]);
                if (qqq == 'D') down(a[i]);
                if (qqq == 'L') left(a[i]);
                if (qqq == 'R') right(a[i]);
                if (qqq == 'F') fix(a[i]);
                if (qqq == 'A'){
                    plane now = a[i]; int cnt = 0;
                    while (ok(now)){
                        if (mp.count({{now.x, now.y}, now.z})){
                            auto t = mp[{{now.x, now.y}, now.z}];
                            int j = t[0];
                            if (i == j){
                                if (t.size() >= 2) j = t[1];
                                else{
                                    move(now);
                                    continue;
                                }
                            }
                            if (samepos(a[i], a[j])) break;
                            if (now.atk > a[j].def) a[j].hp -= now.atk - a[j].def;
                            if (a[j].hp <= 0) a[j].hp = -114514, kil[j] = 1;
                            break;
                        }
                        move(now);
                    }
                }
                if (qqq == 'M'){
                    plane now = a[i]; int cnt = 0;
                    while (ok(now)){
                        if (mp.count({{now.x, now.y}, now.z})){
                            for (auto j : mp[{{now.x, now.y}, now.z}]){
                                if (samepos(a[i], a[j])) continue;
                                if (now.mat > a[j].mdf) a[j].hp -= now.mat - a[j].mdf;
                                if (a[j].hp <= 0) a[j].hp = -114514, kil[j] = 1;
                            }
                        }
                        move(now);
                    }
                }
            }
        }
        for (int i = 1; i <= n; i ++ ){
            cout << a[i].x << " " << a[i].y << " " << a[i].z << " " << (kil[i] ? 0 : a[i].hp) << "\n";
        }
    }
    void single(){ init(), solve(); }
    void multi(){ init(); int T; cin >> T; while (T -- ) solve(); }
    void idmulti(){ init(); int id, T; cin >> id >> T; while (T -- ) solve(); }
};

signed main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    ARIS0_0::single();
}
// 大雪纷飞,可叹雪寒,可赞雪美。旧的灵魂终将褪去,但旧的躯体将永垂不朽
// ARIS0_0 - 9