洛谷P1605 迷宫 题解

 

 

 

题目背景

【问题描述】

给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

【数据规模】

1≤N,M≤5

题目描述
输入输出格式
输入格式:

【输入】

第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点

坐标FX,FY。接下来T行,每行为障碍点的坐标。

输出格式:

【输出】

给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方

案总数。

输入输出样例

输入样例#1:

2 2 1
1 1 2 2
1 2

输出样例#1:

1

题解

一道经典的DFS+回溯,可以说是入门回溯必做题。从起点向四周递归搜索,遇到边界,障碍或走过的路就回溯一步改变方向继续搜索,统计最终到达终点的次数。

Created with Raphaël 2.2.0起点四个方向搜索到边界或障碍或被标记回溯取消标记并向下一个方向搜索到达终点方案数加一标记为走过的路,并继续搜索yesnoyesno

C++代码

#include <iostream>
using namespace std;
int n, m, t;
int ans = 0, x2, y2, x1, y1, map[6][6] = { 0 };
void dfs(int x, int y) {
    if (x<1 || y<1 || x>n || y>m || map[x][y] != 0) {//遇到边界 or 障碍 or 标记 就停止向此方向搜索
        return;
    }
    if (x == x1 && y == y1) ans++;
    map[x][y] = 1;    //添加标记(表示经过了这个位置,下次遇到就不重复经过)
    for (int i = 1; i <= 4; i++) {  //向四个方向搜索
        if (i == 1) {
            dfs(x - 1, y);
        }
        if (i == 2) {
            dfs(x + 1, y);
        }
        if (i == 3) {
            dfs(x, y - 1);
        }
        if (i == 4) {
            dfs(x, y + 1);
        }
    }
    map[x][y] = 0;  //回溯一步(取消标记)
}
int main() {
    cin >> n >> m >> t >> x2 >> y2 >> x1 >> y1;
    for (int i = 1; i <= t; i++) {
        int q, w;
        cin >> q >> w;
        map[q][w] = 2;   //标记为障碍
    }
    dfs(x2, y2);   //从起点开始搜索
    cout << ans;
    return 0;
}
posted @ 2018-10-26 02:31  LackProgramMonkey  阅读(403)  评论(0编辑  收藏  举报
返回顶部