“蛇和梯子”是一个在NXN的(0<N<=20)的方格棋盘上进行的游戏(如下图)
方格从1到N的平方编号。除了第1号和最后编号的方格,其它的格子都有可能有蛇或梯子存在(蛇和梯子的数量及具体位置由输入确定,它们的数量都在100之内并且蛇和梯子不能临近放置,也就是在任何了放置两者首尾的方格之间至少还有一个未放置任何东西的格子)。开始的时候玩家把他们的标志物放在1号格子中。玩家轮流以扔骰子的方式移动他们的指示物。如果一个指示物到达了一条蛇的嘴部,则把它移回蛇的尾部。如果一个指示物到达了一个梯子的底部则将它移动到梯子的顶部。如果你是一个可以自由控制骰子的高手,现在请求出你至少需要扔几次骰子才能到达标为N^2的格子。(比如在上图所示例一中,你的方案应该是走4步到达5并由梯子上升到16,再走4步到达20并由梯子上升到33,然后走3步。这样,你一共需要扔3次骰子。而在例二中,你的方案应该是连扔4个6。
[输入要求]
有多能测试数据,第一行输入N,S,L,(0<N<=20, 0<S<=100, 0<L<=100)其中N表示方格行,S表示蛇的数目,L表示梯子数目,接下S行输入蛇嘴部和尾部,L行输入梯子的底部和顶部。
[输出要求]
每组测试数据对应一个输出,输出能到达标为N^2的格子最小的步数。
解析:这个游戏是一个很经典的搜索问题,要求最快(最小抛骰子的次数),所以思路很明显,广搜,然后搜索效率的话,可以用优先队列;然后图,因为是二维盘旋的,也没有用坐标表示,所以可以把它伸展为一条长为N*N的直线; 以下就是详细的代码实现及解析:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <set> #include <queue> #include <algorithm> #define MAXN 450 #define RST(N)memset(N, 0, sizeof(N)) using namespace std; typedef struct Node //到达某位置时的步数 { int pos; int step; }Node; bool operator < (Node a, Node b) //重载运算符,定义元素加入队列的准则 { return a.step > b.step; } Node start; //开始位置,步数 priority_queue <Node> pq; //优先队列 int Sn[MAXN], Lz[MAXN]; //记录蛇头蛇尾,梯子头/梯子尾 int Si, Ei, res, v[MAXN]; int N, S, L; const int dir[] = {1, 2, 3, 4, 5, 6}; //骰子 bool check(int x) //走下一步要满足的条件 { return x>0 && x<=N*N && !v[x]; } int BFS() { Node cur; int x, xx, value; while(!pq.empty()) { cur = pq.top(), pq.pop(); x = cur.pos, value = cur.step; for(int i=0; i<6; i++) { xx = x + dir[i]; if(check(xx)) { v[xx] = 1; if(xx == N*N) return value+1; if(Sn[xx] != 0 && !v[Sn[xx]]) { //如果踩中蛇头,判断蛇尾是否访问过,如果没有访问过则压进队列,否则不用处理;梯子也是一样; cur.pos = Sn[xx], cur.step = value+1; pq.push(cur); } if(Lz[xx] != 0 && !v[Lz[xx]]) { cur.pos = Lz[xx], cur.step = value+1; pq.push(cur); } } } } return -1; } int main(int argc, char *argv[]) { while(~scanf("%d %d %d", &N, &S, &L)) { RST(Sn), RST(Lz), RST(v); for(int i=0; i<S; i++) { //记录蛇头蛇尾 scanf("%d %d", &Si, &Ei); Sn[Si] = Ei; } for(int i=0; i<L; i++) { //记录梯子头和梯子尾 scanf("%d %d", &Si, &Ei); Lz[Si] = Ei; } while(!pq.empty()) pq.pop(); //清空队列 v[1] = 1; start.pos = 1, start.step = 0; pq.push(start); res = BFS(); if(res != -1) printf("%d\n", res); } return 0; } /* 测试数据: Sample Input: 6 1 3 35 25 3 23 5 16 20 33 Sample Output: 3 */
时间: 2024-10-16 22:08:49