宽度优先搜索


*图片来源:挑战程序设计竞赛(第2版)
最短路径





(
http://m.blog.csdn.net/article/details?id=50768661。
)
#include <iostream>
#include <queue>
using namespace std;
const int MAX_N = 100;
const int MAX_M = 100;
const int INF = 0x3f3f3f3f; //用来表示无穷大
typedef pair<int, int> P; //定义一个坐标形式
char maze[MAX_N][MAX_M + 1];
int N, M;
int sx, sy; //起点的位置
int gx, gy; //终点的位置
int d[MAX_N][MAX_M];//储存起点到某一点的距离
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; //移动方向
void bfs()
{
queue<P> que;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
d[i][j] = INF; //将所有的点置空
que.push(P(sx, sy)); //输入起点
d[sx][sy] = 0;
while (que.size()) //
{
P p = que.front(); que.pop(); //每一队都是一层(累积的距离相等),且只考虑一队
int i;
for (i = 0; i < 4; i++) //输入目前这个点周围四个中没有被访问过的点
{
int nx = p.first + dx[i];
int ny = p.second + dy[i];
if (0 <= nx&&nx < N
&& 0 <= ny&&ny < M
&&maze[nx][ny] != '#'
&&d[nx][ny] == INF)
/*如果这个点(那四个点之一)
1.在这个地图内
2.这个点不是‘#’(不是墙)
3.其值等于无穷大(未被访问过)
*/
{
que.push(P(nx, ny));//满足以上条件即可进入队列
d[nx][ny] = d[p.first][p.second] + 1; //目标位置下移了一次
if(nx==gx && ny==gy) break; //到了终点
}
}
if(i!=4) break;
}
}
int main()
{
cin>>N>>M;
for (int i = 0; i < N; i++)
cin>>maze[i];
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
{
if (maze[i][j] == 'S')
{
sx = i; sy = j;
}
if (maze[i][j] == 'G')
{
gx = i; gy = j;
}
}
bfs();
cout<<d[gx][gy]<<endl;
return 0;
}
7-3 白骑士的移动 (20分)
小S第一次接触国际象棋。他发现国际象棋中的Knight棋子的移动方式和中国象棋中的马类似,移动方式如图所示。 
于是小S在棋盘上随意摆上了一些棋子,其中包括一枚白骑士、一枚黑皇后、若干黑战车和若干黑主教。
小S想知道,如何能在避开黑战车和黑主教的攻击范围的前提下,花费更少的步数吃掉黑皇后。
注1:战车的攻击范围呈直线,和中国象棋的車类似;主教的攻击范围呈斜线,无障碍物情况下可无限延伸。
注2:白骑士只能吃黑皇后,不可以吃掉黑战车和黑主教。
输入格式:
输入仅包含一组样例。
一组样例包含8行(分别对应1-8行),每行包含8个字符,每个字符代表对应行对应列的棋盘格子状况。
其中’ . ‘代表格子上没有摆放任何棋子;’ K '代表格子上摆放的是白骑士; ’ Q '代表格子上摆放的是黑皇后; ’ R '代表格子上摆放的是黑战车; ’ B '代表格子上摆放的是黑主教。
注:题目保证白骑士的初始位置不在黑战车和黑主教的攻击范围内。
输出格式:
如果白骑士可以在避开黑战车和黑主教的攻击的情况下吃掉黑皇后,则输出花费步数的最小值;否则输出"Checkmate"。
输入样例1:
R.B.QB.R
........
........
........
........
........
........
.K......
输出样例1:
4
输入样例2:
....RR.Q
........
.K......
........
........
........
........
........
输出样例2:
Checkmate
#include <iostream>
#include <queue>
using namespace std;
const int M = 8;
const int N = 8;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> P; //定义一个坐标形式
char MAP[M][N + 1];
int sx, sy;
int ex, ey;
int d[M][N];
int dx[8] = {-2, -1, 1, 2, -2, -1, 1, 2}, dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
void read_mark();
void bfs();
int main()
{
read_mark();
bfs();
if(d[ex][ey] != INF)
cout << d[ex][ey] << endl;
else
{
cout << "Checkmate" << endl;
}
}
void read_mark()
{
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
{
cin >> MAP[i][j];
}
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
{
if (MAP[i][j] == 'K')
{
sx = i;
sy = j;
}
if (MAP[i][j] == 'Q')
{
ex = i;
ey = j;
}
if (MAP[i][j] == 'R') //战车攻击范围
{
for (int ii = 0; ii < 8; ii++)
{
if(MAP[i][ii] == 'Q' ||( MAP[i][ii] == 'R' && ii !=j) ||MAP[i][ii] == 'B' )
{break;}
else{
MAP[i][ii] = 'x';
}
}
for (int ii = 0; ii < 8; ii++)
{
if(MAP[ii][j] == 'Q' ||MAP[ii][j] == 'B'||( MAP[ii][j] == 'R' && ii !=i))
break;
else {MAP[ii][j] = 'x';}
}
}
if (MAP[i][j] == 'B') //主教攻击范围
{
int I = i+1, J = j+1;
while (I < M && J <N && I >= 0 && J >= 0 && MAP[I][J] != 'B'&& MAP[I][J] != 'R'&& MAP[I][J] != 'Q')
{ MAP[I++][J++] = 'x';};
I = i-1;J = j-1;
while (I < M && J < N && I >= 0 && J >= 0 && MAP[I][J] != 'B'&& MAP[I][J] != 'R'&& MAP[I][J] != 'Q')
{MAP[I--][J--] = 'x';};
I = i-1;J = j+1;
while (I < M && J < N && I >= 0 && J >= 0 && MAP[I][J] != 'B'&& MAP[I][J] != 'R'&& MAP[I][J] != 'Q')
{MAP[I--][J++] = 'x';};
I = i+1;J = j-1;
while (I < M && J < N && I >= 0 && J >= 0 && MAP[I][J] != 'B'&& MAP[I][J] != 'R'&& MAP[I][J] != 'Q')
{MAP[I++][J--] = 'x';};
}
}
/*for (int i = 0; i < N; i++)
{putchar('\n');
for (int j = 0; j < M; j++)
cout<<MAP[i][j];}*/
}
void bfs()
{
queue<P> que;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
d[i][j] = INF;
que.push(P(sx, sy)); //输入起点
d[sx][sy] = 0;
while (que.size())
{
P p = que.front(); que.pop();
int i;
for (i = 0; i < 8; i++)
{
int nx = p.first + dx[i];
int ny = p.second + dy[i];
if (0 <= nx&&nx < N
&& 0 <= ny&&ny < M
&& MAP[nx][ny] != 'x'
&& MAP[nx][ny] != 'B'
&& MAP[nx][ny] != 'R'
&& d[nx][ny] == INF)
{
que.push(P(nx, ny));
d[nx][ny] = d[p.first][p.second] + 1;
if(nx==ex && ny==ey) break;
}
}
if(i!=8) break;
}
}
/*
R...R..Q
B.......
........
........
........
........
........
....K...
*/
2806

被折叠的 条评论
为什么被折叠?



