首页 > 技术文章 > 10.10 考试T1 低仿机器人

genshy 2020-10-12 09:24 原文

10.10 考试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\)


毒瘤大模拟题,考试的时候写了两个小时才调出来,结果却被输入搞炸了。

先吐糟一下这题的输入:不是你搞个错误的读入是什么鬼啊, \(x\) 竟然还有小数,我也是吐了。

所以这道题,关于 \(cin,scanf\) 他死了,只能用 \(gets\) 一行一行的读。

这道题还是有很多注意的点的。

  • 他坐标是从 \(0,0\) 开始的,关键是这题目中还没给出来,这就很 离谱。
  • 建议开一个栈,把所有填的弹都存起来,这样就会好处理很多。
  • 个人觉得先把每个方向横纵坐标的变化值预处理出来,会很方便,这样会少写很多 \(if,else\) 这类的了。
  • 当机器人停机之后,你还要把剩下的操作都读完。
  • 剩下的就是些实现的具体细节。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int T,n,m,top,cnt,num,pao,robo,x,y,a,b,c,q,k,flag,End;
int map[210][210],d[210][210],sta[210];
int dx[4] = {-1,0,1,0};
int dy[4] = {0,-1,0,1};
char opt[20];
inline int read()
{
	int s = 0,w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	return s * w;
}
void qingkong()
{
	memset(map,0,sizeof(map));
	memset(d,0,sizeof(d));
}
int main()
{
//	freopen("robo.in","r",stdin);
//	freopen("robo.out","w",stdout);
	T = read();
	while(T--)
	{
		qingkong();
		n = read(); m = read(); 
		top = 0, cnt = 0, num = 0; pao = 0; robo = 0; flag = 0, End = 0;
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < m; j++)
			{
				map[i][j] = read();
				if(map[i][j] == 2) d[i][j] = 2;
			}
		}
		x = read(); y = read(); a = read(); b = read(); c = read(); q = read();
		for(int i = 1; i <= q; i++)
		{
			gets(opt);
//			cout<<pao<<" "<<robo<<" "<<flag<<endl;
			if(End == 1 || flag == 1) continue;
			if(opt[0] == 'F' && opt[1] == 'T')
			{
				int k = opt[3] - '0';
    			if((k != 0 && k != 1) || opt[4] == '.') { flag = 1; continue; }
				if(k == 0) pao = (pao + 1 + 4) % 4;
				if(k == 1) pao = (pao + 3 + 4) % 4;
			}
			if(opt[0] == 'F' && opt[1] == 'F')
			{
				int k = opt[3] - '0';
    			if((k != 0 && k != 1) || opt[4] == '.') { flag = 1; continue ; }
				if(k == 1) 
				{
					if(b == 0) continue;
					else sta[++top] = 2, b--;
				} 
				if(k == 0) 
				{
					if(c == 0) continue;
					else sta[++top] = 1, c--;
				}
				if(top > a)
				{
					top--;
					if(k == 1) b++;
					else c++;
					flag = 1;
				}
			}
			if(opt[0] == 'F' && opt[1] == 'E')
			{
//				if(k >= 0) flag = 1;
  				int len = strlen(opt);
    			if(len > 2) { flag = 1; continue; }
				if(top == 0) continue;
				int sx = x, sy = y;
				int k = sta[top--];
				while(map[sx][sy] != 2)
				{
					sx += dx[pao];
					sy += dy[pao];
					if(map[sx][sy] == 1) break;
					if(sx < 0 || sx > n || sy < 0 || sy > m) break;
				}
				if(map[sx][sy] == 1 || sx < 0 || sx >= n || sy <= 0 || sy >= m) continue;
				d[sx][sy] -= k;
				if(d[sx][sy] <= 0) cnt++, map[sx][sy] = 0;
			}
			if(opt[0] == 'W' && opt[1] == 'T')
			{
				int k = opt[3] - '0';
    			if((k != 0 && k != 1) || opt[4] == '.') { flag = 1; continue; }
				if(k == 0) robo = (robo + 1 + 4) % 4;
				if(k == 1) robo = (robo + 3 + 4) % 4;
			}
			if(opt[0] == 'W' && opt[1] == 'G')
			{
				int wei = 3;
				while(opt[wei] >= '0' && opt[wei] <= '9'){k = k * 10 + opt[wei] - '0';	wei++; }
 			    if(k < 0 || k > max(n, m) || opt[4] == '.') { flag = 1; continue ; }
				int sx = x, sy = y;
				for(int j = 1; j <= k; j++)
				{
					sx += dx[robo];
					sy += dy[robo];
					if(map[sx][sy] > 0 || sx < 0 || sx >= n || sy < 0 || sy >= m)
					{
						flag = 1;
						break;
					}
				}
				if(flag == 0) x = sx, y = sy;
			}
			if(opt[0] == 'E') End = 1;
		}
		if(flag == 1 || End == 0) printf("ERROR\n");
		else printf("Complete\n");
		printf("%d %d\n",x,y);
		printf("%d\n",cnt);
		printf("%d %d %d %d\n",pao,robo,b,c);
	}
	fclose(stdin); fclose(stdout);
	return 0;
}

推荐阅读