题目来自洛谷;
附上题目:迷宫问题
[1]题目
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
输入格式
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。
输出格式
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。
[2]输入输出样例:
输入#1
2 2 1
1 1 2 2
1 2
输出#1
1
输入#2
5 5 5
1 2 5 5
2 1
2 2
2 3
2 4
3 4
输出#2
10
[3]题解:
我用二维数组将走过的地方标记且用二维数组将障碍也标记了
这里可以用一个二维数组,也可以用两个
(为了可读性最好使用两个,当然也可以选择用一个二维数组但是不同的数字来标记)
当遇到障碍或撞到墙时返回
当找到终点时计数器加一
PS:
我遇到的问题(我蒟蒻,问题有点多):
- 输入忘记取地址符(这很傻,但就是出现了,而且我就被这个困了好久)
- 不在迷宫里面的条件是(next_x<=0||next_x>N||next_y<=0||next_y>M),一定要有等号;
- 需要在搜这个点之前将它备注为2(走过之后的标记)
- 回溯只需要在搜完这个点之后将它的状态改回最初的状态就可以了,需要注意的是,你要搜的点是你现在所搜点的下一个点,即,你的跳过,返回条件都是为下一个点准备的,都得基于下一个点 eg:if(next_x<=0||next_x>N||next_y<=0||next_y>M)是判断下一个点
- 开始我的回溯也出了错误,就我把 next_x=x-dir[i][0];next_y=y-dir[i][1]; 错误理解为回溯了,人傻了
[3]代码:
//第一个
#include<stdio.h>
#include<stdlib.h>
int cout=0;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int sx,sy,fx,fy,Tx,Ty;
int N,M,T;
int map[100][100]={0};
//int way[100][100]={0};
void dfs(int x,int y)
{
//到了终点,就让计数器cout+1
if(x==fx&&y==fy)
{
cout++;
return;
}
for(int i=0;i<4;i++)
{
int next_x=x+dir[i][0];
int next_y=y+dir[i][1];
//不在这个迷宫里面
if(next_x<=0||next_x>N||next_y<=0||next_y>M)
continue;
//碰到障碍
if(map[next_x][next_y]==1||map[next_x][next_y]==2)
continue;
map[next_x][next_y]=2;
dfs(next_x,next_y);
map[next_x][next_y]=0;
}
return;
}
int main()
{
scanf("%d %d %d",&N,&M,&T);
//起点和终点的坐标
scanf("%d %d %d %d",&sx,&sy,&fx,&fy);
for(int i=0;i<T;i++)
{
scanf("%d %d",&Tx,&Ty);
//将障碍所处的位置记录下来
map[Tx][Ty]=1;
}
map[sx][sy]=2;
dfs(sx,sy);
printf("%d\n",cout);
return 0;
}
//第二个
#include<stdio.h>
int cout=0;
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
int sx,sy,fx,fy;
int N,M,T;
//当map[][]为0时就可以通行,为1时则为障碍不可通行
int map[100][100]={0};
//因为题目的要求就是“每个方格最多经过1次”
//way[][]这个二维数组用来记录这个(x,y)这个点是否走过
int way[100][100]={0};
void dfs(int x,int y)
{
//到了终点,就让计数器cout+1(即,找到了一种方法)
if(x==fx&&y==fy)
{
cout++;
return;
}
for(int i=0; i<4; i++)
{
int next_x=x+dir[i][0];
int next_y=y+dir[i][1];
//在这个迷宫里面且没有碰到障碍才继续搜索
if(next_x>0&&next_x<=N&&next_y>0&&next_y<=M&&map[next_x][next_y]==0&&way[next_x][next_y]==0)
{
way[next_x][next_y]=1;
dfs(next_x,next_y);
way[next_x][next_y]=0;
}
}
return;
}
int main()
{
scanf("%d %d %d",&N,&M,&T);
//起点和终点的坐标
scanf("%d %d %d %d",&sx,&sy,&fx,&fy);
int Tx,Ty;
for(int i=0; i<T; i++)
{
scanf("%d %d",&Tx,&Ty);
//将障碍所处的位置记录下来
map[Tx][Ty]=1;
}
way[sx][sy]=1;
//从起点开始搜
dfs(sx,sy);
printf("%d\n",cout);
return 0;
}