P1747 好奇怪的游戏 广度搜索

P1747 好奇怪的游戏

广搜.

不必在意有两只马,处理一个后重新初始化再次处理即可,剩下的就是很原始的bfs.

注意vis这个标记,在bfs中一个点第一次被遍历到时一定是最快/最短的路径,所以在vis标记之后就不需要再去这个点了.(隐性的剪枝)

如果用dfs+回溯来做的话,就必须等到所有的方案(剪枝后的)穷举之后才能得出答案,相比bfs效率会低很多.

bfs每标记一个vis,都是在向正确答案靠近一步.

dfs回溯完毕时,才能够"总结"出正确答案.

所以求到某已知状态的最短路的问题适合用bfs.

如果最终状态不给出的话,怎么用bfs呢?比如说吃奶酪.这时候暴力方法还是用dfs.

#include <algorithm>    //最近改掉了代码风格,发现还是大括号不换行可读性会更高一些
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

int sx, sy, dx[12] = {-2, -2, -2, -2, -1, -1, 1, 1, 2, 2, 2, 2}, dy[12] = {-2, -1, 1, 2, -2, 2, -2, 2, -2, 2, -1, 1};
bool vis[30][30];
struct S {
    int x, y, t;
};
queue<struct S> que;

void bfs(){
    que.push({sx, sy, 0});
    vis[sx][sy] = true;
    while(!que.empty()){
        struct S tmp = que.front();
        que.pop();

        if(tmp.x == 1 && tmp.y == 1){
            printf("%d\n", tmp.t);
            return;
        }
        for(int i = 0; i < 12; i++){
            int nx = tmp.x + dx[i], ny = tmp.y + dy[i];
            if(nx >= 1 && nx <= 25 && ny >= 1 && ny <= 25 && !vis[nx][ny]){    //马的起点是在(1,1),(20,20)的,但是没有说超出(20,20)没有棋盘,开到25防止可能的漏解
                que.push({nx, ny, tmp.t + 1});                      //注意也没有必要搜索越跳越远的情况
                vis[nx][ny] = true;
            }
        }
    }
}

int main() {
    cin >> sx >> sy;
    bfs();
    cin >> sx >> sy;
    memset(vis, 0, sizeof(vis));
    while(!que.empty())
        que.pop();
    bfs();

    return 0;
}

 

posted @ 2020-11-29 15:19  goverclock  阅读(122)  评论(0编辑  收藏  举报