本游戏和传统贪吃蛇不同的是,初始地图上就会存在所有的食物,吃完食物后也不能增加新的食物!
地图是无穷大的,因此没有撞墙这个说法。
假设蛇初始的坐标为'W'指令代表向上移动,坐标由(x,y)移动到(x,y+1)。
'S'指令代表向下移动,坐标由(x,y)移动到(x,y-1)。
'A'指令代表向左移动,坐标由(x,y)移动到(x-1,y)。
'D'指令代表向右移动,坐标由(x,y)移动到(x+1,y)。
小红想知道,游戏结束的时候,蛇的长度是多少?
第一行输入一个正整数,代表操作的指令长度。
第二行输入一个长度为的,仅包含'W'、'A'、'S'、'D'四种字符的字符串。'W'代表蛇向上移动,'S'蛇向下移动,'A'代表蛇向左移动,'D'代表蛇向右移动。
第三行输入一个正整数,代表食物的数量。
接下来的行,每行输入两个整数
,代表每个食物的坐标。
保证蛇不会相反方向移动,例如,如果上一步蛇向上移动,那么下一步一定不会向下移动。
保证食物不会出现在(0,0)。保证没有两个食物的坐标重合。
一个正整数,代表游戏结束时蛇的长度。
10 WASDDSAASD 3 2 0 -1 1 1 -1
3
蛇可以吃到两个食物,且过程中没有撞到自己的身体。最终长度为3。
10 WWASDDDWAS 5 0 1 -1 1 -1 2 1 1 2 0
5
第五步向右时并不会撞到自己的身体,因为第五步向右到(0,1)时,位于(0,1)的尾巴正好离开了。
但第十步向下时会撞到自己的身体,游戏结束。
总共吃了4个食物,身体长度变成5。
#include <iostream> #include <unordered_map> #include <unordered_set> #include <string> #include <utility> #include <deque> using namespace std; /* 主要使用了两套无序的哈希表来分别存储食物的位置和贪吃蛇的轨迹。使用哈希表是为了更快速地查找。并且使用一个队列来存储 轨迹的先后顺序。每次到达一个新的位置的时候,就要先查看当前位置是否有食物,有的话蛇身长度加一,并且将存储食物的哈希 表中擦除该位置的食物;然后比较轨迹中是否有当前位置,有的话就说明咬到了,游戏结束。 */ struct pair_hash { template <class T1, class T2> size_t operator () (pair<T1, T2> const& pair) const { size_t h1 = hash<T1>()( pair.first); //用默认的 hash 处理 pair 中的第一个数据 X1 size_t h2 = hash<T2>()( pair.second);//用默认的 hash 处理 pair 中的第二个数据 X2 return h1 ^ h2; //异或, } }; int main() { int n; cin >> n; string operation; cin>>operation; //cout << operation << " " << operation.size() << endl; int m; cin >> m; unordered_set<pair<int, int>, pair_hash> food; for (int i = 0; i < m; ++i) { int loc1, loc2; cin >> loc1 >> loc2; food.insert({loc1, loc2}); } /* for(const auto& it : food) { cout << it.first << " " << it.second << endl; } */ unordered_set<pair<int, int>, pair_hash> trace; deque<pair<int, int>> dq; trace.insert({0, 0}); dq.push_back({0, 0}); int cur_locx = 0, cur_locy = 0, body_len = 1; for (int i = 0; i < operation.size(); ++i) { if (operation[i] == 'W') { cur_locy += 1; } else if (operation[i] == 'S') { cur_locy -= 1; } else if (operation[i] == 'A') { cur_locx -= 1; } else { cur_locx += 1; } if (food.find({cur_locx, cur_locy}) != food.end()) { body_len += 1; food.erase({cur_locx, cur_locy}); } //cout << "x = " << cur_locx << " " << " y = " << cur_locy << " body_len = " << body_len << endl; if (trace.size() >= body_len) { int old_x = dq.front().first, old_y = dq.front().second; dq.pop_front(); trace.erase({old_x, old_y}); } if (trace.find({cur_locx, cur_locy}) != trace.end()) { break; } trace.insert({cur_locx, cur_locy}); dq.push_back({cur_locx, cur_locy}); } cout << body_len; return 0; } // 64 位输出请用 printf("%lld")
#include <iostream> using namespace std; int main() { int step; cin>> step; string move; cin >> move; int food_num; cin >> food_num; int food[10000][2] = {}; bool isFood = 0; bool isCrash = 0; for(int i = 0; i<food_num; i++) { cin>> food[i][0] >> food[i][1]; //0为横坐标, 1为纵坐标 } int snake[10001][2] = {}; snake[0][0] = 0; snake[0][1] = 0; int length = 1; int tempx,tempy = 0; for(int i = 0; i<step; i++) { if(isCrash == true) { break; } tempx = snake[length-1][0]; tempy = snake[length-1][1]; //把尾巴的坐标保存起来 for(int j =0; j<length-1; j++) { snake[j+1][0] = snake[j][0] ; snake[j+1][1] = snake[j][1] ; //蛇身坐标数列向后移动, 尾巴舍去, 头不变 //相当于除了头以外都沿蛇身向着头进行了移动 } if(move[i] == 'W') { snake[0][1]++; //如果是W就把新头的纵坐标加1,下面同理 } else if(move[i] == 'A') { snake[0][0]--; } else if(move[i] == 'S') { snake[0][1]--; } else if(move[i] == 'D') { snake[0][0]++; } for(int k = 0; k<food_num; k++) //吃食物检测 { if((snake[0][0]==food[k][0]) && (snake[0][1]==food[k][1])) //如果吃到食物 { length++; //长度增加 snake[length-1][0] = tempx; snake[length-1][1] = tempy; //把舍弃的尾巴加回到数列末尾(吃到食物相当于尾巴还在原位置) for(int m = 0; m<food_num-k-1; m++ ) { food[k+m][0] = food[k+m+1][0]; food[k+m][1] = food[k+m+1][1]; //食物坐标数列向前移动, 被吃掉的食物被舍弃了 } food_num--; //食物数量减少 isFood = true; break; //食物不可能重叠, 吃到了就可以跳过剩余检测了 } } for(int n = 3; n<length-1; n++) //撞死检测, 由于机制问题蛇是不可能撞到头及其后面的两个点的 { // if(isFood == true) // { // break; //不可能在吃到食物的同时撞死 // } if((snake[0][0] == snake[n][0]) && (snake[0][1] == snake[n][1])) { isCrash = true; break; //撞到身体任意一个位置,游戏结束 } } isFood = false; } cout << length << endl; return 0; } // 64 位输出请用 printf("%lld")
思路:用队列模拟贪吃蛇的运动状态,并注意若前方没有食物,则尾部先向前移动,头部再向前移动;若前方有食物,则尾部不移动,头部向前移动
n = int(input()) ops = input() m = int(input()) food_pos = set() for _ in range(m): i, j = list(map(int, input().split())) food_pos.add((i,j)) body_pos = [(0,0)] for i in range(n): op = ops[i] if op == 'W': x, y = body_pos[-1][0], body_pos[-1][1]+1 elif op == 'S': x, y = body_pos[-1][0], body_pos[-1][1]-1 elif op == 'A': x, y = body_pos[-1][0]-1, body_pos[-1][1] else: x, y = body_pos[-1][0]+1, body_pos[-1][1] if (x,y) in body_pos[1:]: break if (x,y) in food_pos: food_pos.remove((x,y)) else: body_pos.pop(0) body_pos.append((x,y)) print(len(body_pos))
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String l1 = in.nextLine(); int num = Integer.parseInt(l1); String op = in.nextLine(); String l3 = in.nextLine(); int foodnum = Integer.parseInt(l3); Vector<String> food = new Vector<>(foodnum); for(int i=0;i<foodnum;i++){ String pos = in.nextLine(); String p[] = pos.split(" "); food.add((Integer.parseInt(p[0]))+"-"+((Integer.parseInt(p[1])))); } int x=0,y=0,res=0; Deque<String> snake = new ArrayDeque<>(num); snake.add("0-0"); for(int i=0;i<num;i++){ switch (op.charAt(i)){ case 'W': y+=1; if(food.contains(x+"-"+y)) { snake.add(x+"-"+y); food.remove(x+"-"+y); } else { snake.pop(); if(snake.contains(x+"-"+y)){ res=1; i=num-1; }else{ snake.add(x+"-"+y); } } break; case 'A': x-=1; if(food.contains(x+"-"+y)) { snake.add(x+"-"+y); food.remove(x+"-"+y); } else { snake.pop(); if(snake.contains(x+"-"+y)){ res=1; i=num-1; }else{ snake.add(x+"-"+y); } } break; case 'S': y-=1; if(food.contains(x+"-"+y)) { snake.add(x+"-"+y); food.remove(x+"-"+y); } else { snake.pop(); if(snake.contains(x+"-"+y)){ res=1; i=num-1; }else{ snake.add(x+"-"+y); } } break; case 'D': x+=1; if(food.contains(x+"-"+y)) { snake.add(x+"-"+y); food.remove(x+"-"+y); } else { snake.pop(); if(snake.contains(x+"-"+y)){ res=1; i=num-1; }else{ snake.add(x+"-"+y); } } break; } } res += snake.size(); System.out.println(res); } }值得注意的有以下两个点: