抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

luogu 阅读链接
灭鼠行动

前言

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

细节

  • 神秘射线停止一切生理活动(包括成长),会暂停,但不会打断繁殖。
  • 繁殖后要动一下(包括旋转),才能继续繁殖。
  • 顺序:武器 -> 繁殖 -> 移动。
  • 注意老鼠刚出生时的年龄。
  • 注意时间单位时刻的区别。
  • 繁殖是某点恰好有两只异性老鼠。
  • 岔路的拐弯与当前这只老鼠面对岔路的次数奇偶性有关。
  • 注意实时更新老鼠的数量。
  • 我用的是 list 保存老鼠,在删除时要注意指针失效的问题。

代码

也就 3.1KB,一百行左右,是我写的最短紫色模拟题了。
我不会告诉你我猪国杀写了 7.7KB。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<bits/stdc++.h>
using namespace std;
#define FL(a, b, c) for(int a = (b), a##end = (c); a <= a##end; a++)
#define FR(a, b, c) for(int a = (b), a##end = (c); a >= a##end; a--)
#define loop(it) for(it = mice.begin(); it != mice.end(); it++)
#define cheakover if(mtot > Max)return cout << -1, 0
#define right(x) ((x << 1) % 15)
#define left(x) ((x ^ 1) ? (x >> 1) : 8)
constexpr int E(2), S(4), W(8), N(1);

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;
}