1010考试T1
1010考试T1
题目描述
小文给这个小机器人布置了 n*m 的场地(场地外用障碍围住),在场地上设置了障碍、水池和靶子。其中,障碍是不可以通过并且无法用水晶弹打掉的,靶子无法通过、但是可以被水晶弹打掉,水池也无法通过、但是水晶弹可以通过水池。
小文检查了一下小机器人,发现它的指令系统很简单。该系统中一共有 6 种指令,指令的使用说明如下:
“FT x” :该指令表示炮台的 90°转动,其中 x∈[0,1],x∈Z,并且 0、1 分别表示逆时针和顺时针。
“FF i” :该指令表示填弹,填弹后弹仓剩余弹量减一,弹夹剩余弹量加一,其中 i∈[0,1]且 i∈Z,i 为 1 表示所填水晶弹为大弹丸,为 0 表示所填水晶弹为小弹丸。
“FE” :该指令表示发射水晶弹,水晶弹的发射方向同炮台的朝向,发射的水晶弹为最后一个填入弹夹的水晶弹,指令执行后弹夹容量减一。
“WT x” :该指令表示机器人的 90°转动, 其中 x∈[0,1],x∈Z, 并且 0、1 分别表示逆时针和顺时针。
“WG y” :该指令表示机器人前进 y 步,其中 y∈[0,max(m,n)),y∈Z。
“END” :该指令将返回“Complete”并停机,不同于编译器先编译后运行,END(及其他将造成停机的情况)后的指令均被无视。
小文给了你场地、小机器人的初始状态和指令集并拜托你帮他计算出小机器人的返回内容、停下的位置、打掉的靶子数量以及小机器人的状态。
注意: (一)弹夹无弹的情况下将跳过 FE 指令,弹仓无相应弹丸的情况下将跳过 FF 指令;
(二)大水晶弹一发打掉靶子,小水晶弹需两发打掉靶子,靶子打掉后变成空地可通过;
(三)小机器人将在以下情况下返回“ERROR”并停机: (1)在弹夹已满的情况下继续填弹; (2)撞上障碍(包括未被打掉的靶子)或者撞进水池; (3)指令后的参数不满足要求(例:“FE 10”); (4)无“END”指令;
输入格式
输入文件的第一行为一个正整数 t,表示该题有 t 组数据。
对于每一组数据: 第 1 行为两个正整数 n m第 2~(n+1)行,每行 m 个正整数,表示地图,其中 1 代表障碍,2 代表靶子,3 代表水池,0 代表空地。
第 n+2 行有 6 个正整数,依次为:机器人横坐标 x 和纵坐标 y,弹夹的容量 a,弹仓内剩余大水晶弹量 b,弹仓内剩余小水晶弹量 c,小文的指令数量 k。(弹夹初始容量默认为 0,炮台和机器人的默认朝向为向上)。
第(n+3)~(n+3+k)行,每行一个指令,指令的正确格式和正确参数见题目描述(数据中无双引号)(不满足要求的参数大小<=10,长度<=3)。
输出格式
输出文件共 t*4 行,其中对于每组数据:
第 1 行输出小机器人的返回内容(“Complete”或“ERROR”,不输出双引号)。
第 2 行输出小机器人停下的位置的横纵坐标(用空格隔开)。
第 3 行输出小机器人打掉的靶子数量 h。
第 4 行依次输出炮台的朝向、机器人的朝向、弹仓剩余大水晶弹量、弹仓剩余小水晶弹量,用空格隔开,其中0、1、2、3 分别表示上左下右。 若机器人返回“ERROR”后停机,则输出数据为执行错误指令前的数据。
对于全部数据,t<=20,n、m<=200,a<=30,b、c<=100,k<=100。
妹错!妹错!大模拟!我tm直接吐。考试时调了两个多小时,考完调了一个小时才过……还是代码能力有点差吧。
这些是细节:
1.读入操作用\(getline\)或者\(gets\),虽然\(gets\)已经死了。因为有时候题目会让你判断错误参数,有些不该输入的多输入了,所以只能用这个,\(cin\)会挂。
2.读入数字要用快读,里面有\(getchar\),用\(cin\)和\(scanf\)同样会挂。
3.注意往前走的步数不一定是个位数,也可能是二位数,三位数。
4.注意题目让你输出错误指令之前的东西,比如错误指令执行到一半时的东西就不能输出,我一开始就读错题了。
5.矩阵从\((0, 0)\)开始。
#include <bits/stdc++.h>
using namespace std;
inline long long read() {
long long s = 0, f = 1; char ch;
while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
return s * f;
}
const int N = 205, inf = 1e9;
int T, n, m, k, rto, pto, top, tag, sum, nowx, nowy, resa, resb, resc;
int a[N][N], sta[N];
char ch[N];
void init() {
n = read(), m = read();
top = rto = pto = sum = 0; tag = 2;
for(int i = 0;i < n; i++)
for(int j = 0, x;j < m; j++) {
x = read();
if(x == 1) a[i][j] = inf, sum ++;
if(x == 2) a[i][j] = 2, sum ++;
if(x == 3) a[i][j] = -1;
if(x == 4) a[i][j] = 0;
}
nowx = read(); nowy = read();
resa = read(); resb = read(); resc = read(); k = read();
}
void FT() {
int x = ch[3] - '0';
if((x != 0 && x != 1) || ch[4] == '.') { tag = 1; return ; }
if(x == 0) { pto ++; pto %= 4; }
if(x == 1) { pto --; (pto += 4) %= 4; }
}
void WT() {
int x = ch[3] - '0';
if((x != 0 && x != 1) || ch[4] == '.') { tag = 1; return ; }
if(x == 0) { rto ++; rto %= 4; }
if(x == 1) { rto --; (rto += 4) %= 4; }
}
void FF() {
int x = ch[3] - '0';
if((x != 0 && x != 1) || ch[4] == '.') { tag = 1; return ; }
if(x == 1) {
if(resb == 0) return ;
if(top + 1 > resa) { tag = 1; return ; }
sta[++ top] = 2; resb --;
}
if(x == 0) {
if(resc == 0) return ;
if(top + 1 > resa) { tag = 1; return ; }
sta[++ top] = 1; resc --;
}
}
void FE() {
int x = strlen(ch);
if(x > 2) { tag = 1; return ; }
if(top == 0) { return ; }
int y = sta[top --];
if(pto == 0)
for(int i = nowx;i >= 0; i--) if(a[i][nowy] > 0) { a[i][nowy] -= y; a[i][nowy] = max(0, a[i][nowy]); break; }
if(pto == 2)
for(int i = nowx;i < n; i++) if(a[i][nowy] > 0) { a[i][nowy] -= y; a[i][nowy] = max(0, a[i][nowy]); break; }
if(pto == 1)
for(int i = nowy;i >= 0; i--) if(a[nowx][i] > 0) { a[nowx][i] -= y; a[nowx][i] = max(0, a[nowx][i]); break; }
if(pto == 3)
for(int i = nowy;i < m; i++) if(a[nowx][i] > 0) { a[nowx][i] -= y; a[nowx][i] = max(0, a[nowx][i]); break; }
}
int judge(int x, int y) {
if(x < 0 || x >= n || y < 0 || y >= m) return 0;
if(a[x][y] == -1 || a[x][y] > 0) return 0;
return 1;
}
void WG() {
int x = 0, now = 3;
while(ch[now] >= '0' && ch[now] <= '9') {
x = x * 10 + ch[now] - '0'; now ++;
}
if(x < 0 || x > max(n, m) || ch[4] == '.') { tag = 1; return ; }
int tmp1 = nowx, tmp2 = nowy;
if(rto == 0)
{ while(x --> 0) { int tx = tmp1 - 1; if(judge(tx, tmp2)) tmp1 = tx; else { tag = 1; return ; }} }
if(rto == 2)
{ while(x --> 0) { int tx = tmp1 + 1; if(judge(tx, tmp2)) tmp1 = tx; else { tag = 1; return ; }} }
if(rto == 1)
{ while(x --> 0) { int ty = tmp2 - 1; if(judge(tmp1, ty)) tmp2 = ty; else { tag = 1; return ; }} }
if(rto == 3)
{ while(x --> 0) { int ty = tmp2 + 1; if(judge(tmp1, ty)) tmp2 = ty; else { tag = 1; return ; }} }
nowx = tmp1; nowy = tmp2;
}
void work() {
for(int i = 1;i <= k; i++) {
gets(ch);
if(ch[0] == 'F' && ch[1] == 'T') { if(tag == 2) FT(); }
if(ch[0] == 'F' && ch[1] == 'F') { if(tag == 2) FF(); }
if(ch[0] == 'F' && ch[1] == 'E') { if(tag == 2) FE(); }
if(ch[0] == 'W' && ch[1] == 'T') { if(tag == 2) WT(); }
if(ch[0] == 'W' && ch[1] == 'G') { if(tag == 2) WG(); }
if(ch[0] == 'E') { if(tag == 2) tag = 0; }
}
}
void print() {
if(tag >= 1) { printf("ERROR\n"); }
else { printf("Complete\n"); }
printf("%d %d\n", nowx, nowy);
int tmp = 0;
for(int i = 0;i < n; i++)
for(int j = 0;j < m; j++) if(a[i][j] > 0) tmp ++;
for(int i = 0;i < n; i++)
for(int j = 0;j < m; j++) a[i][j] = 0;
printf("%d\n", sum - tmp);
printf("%d %d %d %d\n", pto, rto, resb, resc);
}
int main() {
T = read();
while(T --> 0) {
init(); work(); print();
}
fclose(stdin); fclose(stdout);
return 0;
}