题目传送门
本题很水,只能算上中模拟吧。
第一步就是选一个合适的数据结构存储蛇身,毫无疑问deque双端队列是最好的选择,因为这样移动会更方便。
下一步要输入地图找蛇和蛇的头,找蛇头很好找,遍历一遍数组即可,而找蛇可以用dfs找连通块,但有人会有疑问为什么可以用连通块扫蛇身呢,不会混淆吗?
不会的。
因为题目保证了:
图中的蛇不会引起混淆(对于任意蛇头,最多只有一块蛇身于其相连,而蛇身最多为二连块),且数据保证图中的蛇均可以判断身体与头的对应关系,不会造成蛇身形态多解。
这很重要,所以可以用dfs连通块求蛇身。
int n , m , k;
int cnt_snack , cnt_food;//分别是蛇的数量和事物的数量
int dx[4] = {
0 , 0 , 1 , -1} , dy[4] = {
1 , -1 , 0 , 0};
bool vis[205][205];
char c[205][205] , d[205][205];//地图和输入的操作
struct node{
int x , y;
};
deque <node> q[25];
void dfs(int x , int y){
vis[x][y] = 1;
q[cnt_snack].push_back((node){
x , y});//存储进双端队列首
for(int i = 0; i < 4; i++){
int nx = x + dx[i] , ny = y + dy[i];
if(c[nx][ny] == '#' && !vis[nx][ny])// 是#并且没有遍历过
dfs(nx , ny);
}
}
而移动就需要判断是否碰壁,是否吃到食物等等,细节很多,代码如下:
void died(deque <node> &q){
//蛇无了
while(!q.empty()){
cnt_food++;//食物++
c[q.front().x][q.front().y] = '&';//变成食物
q.pop_front();
}
return;
}
void eat(deque <node> &q , int x , int y){
//吃食物
cnt_food--;//食物减少
c[x][y] = '@';//蛇头移动
c[q.front().x][q.front().y] = '#';//蛇身移动
q