CometOJ--龙颈之玉 -五色的弹丸

龙颈之玉 -五色的弹丸

题目描述

Gromah 最近沉迷于一款叫做 “贪吃蛇大作战” 的游戏。

给定一个 n×m 的地图,其中有些格子是空的,有些格子上有食物。初始时贪吃蛇的头在地图中的某个格子上,且贪吃蛇初始只有一个头,每次 Gromah 会控制贪吃蛇的头朝着上下左右四个方向中的一个方向移动一个单位,如果贪吃蛇的头撞到了墙(即坐标不在 (1,1)−(n,m) 范围内),则其立即死亡,否则如果贪吃蛇的头所到达的格子上有一个食物,则贪吃蛇会吃掉这个食物,然后身体立即增加 1 的长度,当然一个食物被吃掉之后就会消失。

具体地,每当进行一次移动,如果没有吃掉一个食物,则贪吃蛇在头部按照给定方向进行移动的同时,身体的每一段也朝着前一段身体的方向进行移动;如果吃掉了一个食物,则只有头部进行移动,原来身体不进行移动,原来的头部位置长出一个单位的身体,即贪吃蛇的身体增加 1 的长度。

特别地,贪吃蛇的头可以和自己的身体重合(起码游戏里是这样子的),保证贪吃蛇的初始位置上不存在食物。

现给定地图,贪吃蛇的头的初始位置,移动序列。如果贪吃蛇中途撞到了墙,则输出GG,否则如果贪吃蛇最后还活着,输出地图的最后状态,具体请见输出格式及样例输出。

输入描述

第一行两个整数 n,m (1≤n,m≤400),表示地图大小。
接下来 n 行,每行一个长为 m 的只包含’.’,‘o’和’@‘的字符串 s,表示地图。其中’.'表示没有食物,‘o’表示有一个食物,’@‘表示贪吃蛇的头的初始位置。
接下来一行一个只包含’W’,‘A’,‘S’,'D’的字符串t (1≤∣t∣≤10^5 ),表示操作序列,其中’W’表示向上,'A’表示向左,‘S’表示向下,‘D’表示向右。保证地图中有且仅有一个’@’。

输出描述

如果贪吃蛇中道崩殂,输出GG,否则输出 n 行,每行一个长为 m 的字符串,表示地图的最后状态。其中用’.'表示空地,‘o’表示有一个食物,’@‘表示贪吃蛇的头,‘X’表示贪吃蛇的身体。
特别地,如果贪吃蛇的头与身体重合,在相应格子输出’@’。

学到了dalao的一种思路—deque容器…自己当初写的时候想到用容器,刚开始用vector发现没法处理遇到’.'的情况,之后感觉可以回溯来写,在回溯过程中去判断所以用了栈,但是没法同时处理蛇身体和头有重合与无重合的情况…
deque双端队列是个好东西。。。或者也可以记录蛇身长度然后模拟移动过程。
代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int>pii;
deque<pii>q;

char c[500][500], op[100005];

int main (){
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;++i){
		for (int j = 1;j <= m;++j){
			cin >> c[i][j];
			if (c[i][j] =='@'){
				c[i][j] = '.';
				q.push_back(pii(i, j));
			}
		}
	}
	cin >> op;
	int T = strlen(op), len = 1;
	bool flag = false;
	for (int i = 0;i < T;++i){
		int nowx = q[0].first;
		int nowy = q[0].second;
		if (op[i] == 'W' && --nowx < 1){
			flag = true;
			break;
		}
		if (op[i] == 'S' && ++nowx > n){
			flag = true;
			break;
		}if (op[i] == 'D' && ++nowy > m){
			flag = true;
			break;
		}
		if (op[i] == 'A' && --nowy < 1){
			flag = true;
			break;
		}
		q.push_front(pii(nowx, nowy));
		if (c[nowx][nowy] == 'o'){
			c[nowx][nowy] = '.';
		} else {
			q.pop_back();
		}
	}
	if (flag){
		cout << "GG" << endl;
		return 0;
	} else {
		for (int i = 0;i < q.size();++i){
			c[(q.at(i)).first][(q.at(i)).second] = 'X';
		}
		c[q[0].first][q[0].second] = '@';
	}
	
	for (int i = 1; i <= n;++i){
		for (int j = 1;j <= m;++j){
			cout << c[i][j];
		}
		cout << endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值