题解:P5506 封锁 / ARIS0_0 - 9
前言
是不是一车题解被 hack 了,补一个。
话说数据确实很水,现在还是很水。
思路
首先,这题的难点在于读题。
读完题发现其实重头戏在于移动,子弹,激光。
这里先把其他的讲一下,重头戏一会儿细说。
对于每一个无人机,你维护一个结构体。
struct plane{
int x, y, z, h, f, atk, def, mat, mdf, hp, fix;
} a[N];
含义如题。
对于 F,L,R,U,D,直接按照题意改变即可。
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 记下每一个位置有哪些点,然后对于子弹,直接不断移动,知道移动出了边界(注:此处边界为
但凡找到一个点,上面有飞机,你就考虑这个点上的编号最小的,不是自己的飞机,然后如果能造成伤害就造成伤害。
激光
激光和子弹类似,但是不是找到第一个,而是找到所有的。
至此完结。
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