给一个n×m的迷宫,‘#’为墙不可通行,'.'为可经过的点,S为起点,E为终点, 给出一串包含0,1,2,3的字符串,已知0123与上下左右对应,求有几种对应方式使得通过字符串的操作可以从S到E
Input
第一行包括两个整数n m(2 ≤ n, m ≤ 50),接下来是一个n×m的迷宫,只包含'.','#',S,E,在下来是一个字符串s,只包含0,1,2,3, (1 ≤ |s| ≤ 100)
Output
输出总共有多少种对应方式可以通过字符串的相应操作从S到E
Input
5 6
.....#
S....#
.#....
.#....
...E..
333300012
Output
1
Input
6 6
......
......
..SE..
......
......
......
01232123212302123021
Output
14
Input
5 3
...
.S.
###
.E.
...
3
Output
0
以前做惯了 自己直接设置方向的题目,这道题目不是自己设置反向,而是给出一串数字由0 1 2 3 组成,某个数字代表一个方位,你自己设置0 1 2 3 各自代表什么,看看按照这个指令串,能否从START 走到END ,一看题目,这是个啥,然而自己太菜,没有见过什么更高级的题目。本题目解法 就是将0 1 2 3 的全排列全求出来,一个一个去判断,这 4 个数的全排列 就相当于一个方向了 ,然后再套 DFS 搜索模板 ,这个DFS 搜索不用再一次一次每个方向的递归,因为题目已经告诉你走的方向和步数,就看看在指定步数内,能不能撞墙和走到终点就行了,就可以AC 了。
代码:
#include<stdio.h>
#include<iostream>
using namespace std;
#include<string.h>
#include<string>
const int maxn=1005;
int a[]={0,0,1,-1};
int b[]={1,-1,0,0};
char maap[maxn][maxn];
int m,n;
int x1,y1,ox,oy,l,sum;
int vis[maxn];
int c[maxn];
char zhiling[maxn];
void dfs(int x)
{
if(x==4)
{
int xx=x1;
int yy=y1;
for(int i=0;i<l;i++)
{
xx+=a[c[zhiling[i]-'0']];
yy+=b[c[zhiling[i]-'0']];
if(xx<0||yy<0||xx>=m||yy>=n||maap[xx][yy]=='#')
return ;
if(xx==ox&&yy==oy)
{
sum++;
return ;
}
}
}
else
{
for(int i=0;i<4;i++)
if(!vis[i])
{
c[x]=i;
vis[i]=1;
dfs(x+1);
vis[i]=0;
}
}
}
int main()
{
int i,j;
cin>>m>>n;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
cin>>maap[i][j];
if(maap[i][j]=='S')
{
x1=i;
y1=j;
}
if(maap[i][j]=='E')
{
ox=i;
oy=j;
}
}
cin>>zhiling;
l=strlen(zhiling);
dfs(0);
cout<<sum<<endl;
return 0;
}
DFS 全排列 与DFS 搜索的结合 很巧妙 ,推荐大家可以 去刷刷 CF(codeforces)