蛇与梯子游戏 (BFS + priority_queue)

“蛇和梯子”是一个在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

蛇与梯子游戏 (BFS + priority_queue)的相关文章

hdu 1175 bfs+priority_queue

连连看 如上图所示如果采用传统bfs的话,如果按照逆时针方向从(1,1)-->(3,4)搜索,会优先选择走拐四次弯的路径导致ans错误: Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 34028    Accepted Submission(s): 8438 Problem Description "连连看"相信很多

hdu2209翻纸牌游戏(bfs+状态压缩)

Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作. Input 有多个case,每个case输入一行01符号串(长度不超过20),1表

HLG 1613 迷宫问题 (BFS + priority_queue)

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1613 Description : 小z身处在一个迷宫中,小z每分钟可以走到上下左右四个方向的相邻格之一.迷宫中有一些墙和障碍物. 同时迷宫中也有一些传送门,当小z走到任意一个传送门时,可以选择传送到其他任意的传送门(传送是不花费时间的), 当然也可以停留在原地.现在小z想知道走出迷宫需要花费的最少时间. Input : 输入第一行为组

hdoj1242(bfs+priority_queue)

之前用dfs剪枝AC了,http://www.cnblogs.com/ediszhao/p/4741825.html,这次用bfs+priority_queue来尝试解题 题意:拯救行动,天使r有多个朋友a(friends,在这里被坑了几次,没看清题意),天使被关在牢房里,等着朋友来拯救,求拯救天使的最短距离. 以天使为起点进行bfs,找到的a就是最小拯救时间值. #include <iostream> #include <cstring> #include <queue&g

原生js写的贪吃蛇网页版游戏

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>原生js写的贪吃蛇网页版游戏</title> </head> <body><div><A href="http://www.999jiujiu.com/">h

java涉嫌蛇和梯子的游戏

/** * @Author jiangfq * */ package com.test; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @author jiangfq * */ public class Game { private static int[][] me = new int[1][1]; private static List<Ladder> ladders =

hdu 1254(推箱子游戏bfs+状态标记)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5181    Accepted Submission(s): 1439 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N

HDU 5336 XYZ and Drops(模拟十滴水游戏 BFS啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5336 Problem Description XYZ is playing an interesting game called "drops". It is played on a r?c grid. Each grid cell is either empty, or occupied by a waterdrop. Each waterdrop has a property &quo

FZU1892接水管游戏-BFS加上简单的状态压缩和位运算处理

原题地址:http://acm.fzu.edu.cn/problem.php?pid=1892 Problem 1892 接水管游戏 Accept: 108    Submit: 498 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description 接水管游戏的规则如下: 1.在N*N大小的方格上有两个特别的水管,分别为进水口和出水口: 2.有7种1*1大小的水管需要放在这N*N大小的方格内,使得水流能够从进水口经过这些