题目链接:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98233#problem/F
dfs与bfs的水题,就是沿最左边走,沿最右边走,题意不太好理解。
题意:
1.沿着左边的墙从 S 一直走,求到达 E 的步数。
2.沿着右边的墙从 S 一直走,求到达 E 的步数。
3.求最短路。
大体思路:
最短路就不用说了,一个bfs搞定。另外两种,有点麻烦,不过搞清楚转向了还是很容易的。
拿沿着最左边走举例吧。当前方向如果是向上,那么先往左走,如果像左走不了,就像右逐步旋转,搜索方向顺序左,上,右,下。
当前方向 检索顺序
↑ : ← ↑ → ↓
→ : ↑ → ↓ ←
↓ : → ↓ ← ↑
← : ↓ ← ↑ →
1 0 1 2 3
↑ : ← ↑ → ↓
用一个数组下标来表示方向,新方向下标等于(curDir-1+i+4)%4
代码:
代码有点挫。QAQ
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int i;
int j;
};
char map[45][45];
int vis[45][45];
int h, w;
struct node S;
struct node E;
struct node leftMove[4] = { { 0, -1 }, { -1, 0 }, { 0, 1 }, {1,0} };
struct node rightMove[4] = { { 0, 1 }, { -1, 0 }, { 0, -1 }, {1,0} };
int stepLeft;
int stepRight;
int stepMin;
int flag;
void leftDfs(int curDir,struct node cur)
{
stepLeft++;
if (cur.i == E.i && cur.j == E.j)
{
flag = true;
return;
}
for (int i = 0; i < 4; i++)
{
int dir = (curDir - 1+i + 4) % 4;
struct node x = cur;
x.i += leftMove[dir].i;
x.j += leftMove[dir].j;
if (!flag&&x.i >= 0 && x.i<h && x.j >= 0 && x.j<w&&map[x.i][x.j] != '#')
{
leftDfs(dir,x);
}
}
}
void rightDfs(int curDir,struct node cur)
{
stepRight++;
if (cur.i == E.i && cur.j == E.j)
{
flag = true;
return;
}
for (int i = 0; i < 4; i++)
{
int dir = (curDir - 1 + i + 4) % 4;
struct node x = cur;
x.i += rightMove[dir].i;
x.j+=rightMove[dir].j;
if (!flag&&x.i >= 0 && x.i<h && x.j >= 0 && x.j<w&& map[x.i][x.j] != '#')
{
rightDfs(dir,x);
}
}
}
void bfs()
{
queue<node> q;
vis[S.i][S.j] = 1;
q.push(S);
struct node cur;
while (!q.empty())
{
cur = q.front();
if (cur.i == E.i && cur.j == E.j)
{
return;
}
q.pop();
for (int i = 0; i < 4; i++)
{
struct node x = cur;
x.i += rightMove[i].i;
x.j += rightMove[i].j;
if (x.i >= 0 && x.i < h && x.j >= 0 && x.j < w&&!vis[x.i][x.j] && map[x.i][x.j] != '#')
{
vis[x.i][x.j] = vis[cur.i][cur.j]+1;
q.push(x);
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
while (n--)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
stepLeft = 0;
stepRight = 0;
stepMin = 0;
scanf("%d%d",&w,&h);
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
cin >> map[i][j];
if (map[i][j] == 'S')
{
S.i = i;
S.j = j;
}
if (map[i][j] == 'E')
{
E.i = i;
E.j = j;
}
}
}
flag = false;
leftDfs(1,S);
flag = false;
rightDfs(1,S);
bfs();
printf("%d %d %d\n",stepLeft,stepRight,vis[E.i][E.j]);
}
system("pause");
return 0;
}