题面(from luogu)
迷宫
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
数据规模:1≤N,M≤5
输入格式:
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。
输出格式:
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。
样例.in
2 2 1
1 1 2 2
1 2
样例.out
1
题目分析
这是一道同样经典的深搜题目,笔者也就不多瞎分析l
具体的步骤也就是这样的:
搜索部分:
①边界的确定;
②4个方向什么样能走;
main函数:
①打上路障标记,在图外设一圈围墙(堤防走出地图了)
②调用搜索函数
大体框架:
void search(int x,int y)
{
if (走到终点了)
{
ans++;
return;
}
else //反之,继续找
{
向4个方向走;
if (没走过 || 没走到围墙处 || 走回去了(走到了重复的地方)) continue; //跳过
else //反之向前走
{
打标记;
向前搜;
回溯;
}
}
}
代码
#include <bits/stdc++.h>
using namespace std;
int dx[5]={0,-1,0,0,1}; //介值
int dy[5]={0,0,1,-1,0};
int vis[7][7],a[7][7],sx,sy,fx,fy,ans,n,m,t; //vis是记录当前元素是否访问过,a是同map(地图)数组
void search(int x,int y)
{
if (x == fx && y == fy) //走到终点
{
ans++; //方案数++
return; //回到上一步
}
else //反之,继续向两个方向走
{
for (int i = 1; i <= 4; i++)
if (a[x+dx[i]][y+dy[i]] == 2 || a[x+dx[i]][y+dy[i]] == 1 || vis[x+dx[i]][y+dy[i]] == 1) continue;
//如果:①没走过 ②没走到围墙处 ③走回去了(走到了重复的地方) 跳过目前元素
else
{
vis[x][y] = 1; //设置占位符
search(x+dx[i],y+dy[i]); //向该方向走
vis[x][y] = 0; //回溯
}
}
}
int main()
{
int tx,ty;
cin>>n>>m>>t; //输入
cin>>sx>>sy>>fx>>fy;
for (int i = 0; i <= n+1; i++) //先比原来的多打一圈,但是要主题所有的都是围墙判断符,之后会被覆盖的
for (int j = 0; j <= m+1; j++)
a[i][j] = 2;
for (int i = 1; i <= t; i++)
{
cin>>tx>>ty; //输入路障的坐标
a[tx][ty] = 1; //设置路障
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (a[i][j] == 2) a[i][j] = 0; //将多余的围墙元素覆盖成正常的道路元素(可以走的)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
vis[i][j] = 0; //判断的数组视为全部可以走
search(sx,sy); //导入起点坐标,开搜
cout<<ans; //输出
return 0; //完美的结束程序
}
**蒟蒻新星c_uizrp_dzjopkl原创**