# BFS简单专题总结 BFS的入门之路

struct node
{
int x, y, step;
};//根据需要定义结构体
int vis[MAX][MAX]={0};//二维三维之类的看题目给的条件
queue<node> q;
q.push(start);//把起点压入队列
node pre,nex;
vis[start.x][start.y]=1;//一般是设置为1，如果有其他需要可以更改
while(!q.empty()){
pre = q.front();
if(xxx) break; //xxx是终点的判断
q.pop();
for(int i=0;i<4;i++){//i不一定是小于4，看题目来定
if(xxxx){//如果满足怎样的条件将这种情况压入队列
q.push(xx);
vis[xx.x][xx.y]=1;//别忘了标记来过
}
}
}
if(!q.empty()){
//就是找到了终点
}
else{
//没有找到终点
}

## 入门的是遇到的一道马跳题，比较简单

###### Knight Moves

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy.
Of course you know that it is vice versa. So you offer him to write a program that solves the “difficult” part.

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

### Input Specification

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and a digit (1-8) representing the row on the chessboard.

### Output Specification

For each test case, print one line saying “To get from xx to yy takes n knight moves.”.

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

### Sample Output

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.

#include <stdio.h>
#include <queue>
using namespace std;
struct node
{char x;
int y,step;};
int main(){
char x1,x2;
int y1,y2;
queue<node> q;
node start,temp;
while(~scanf("%c%d %c%d",&x1,&y1,&x2,&y2)){
getchar();
int vis[150][9]={0};
for(int i=0;i<150;i++)
for(int j=0;j<9;j++)
vis[i][j]=0;
while(!q.empty())//清空
q.pop();
start.x=x1;start.y=y1;start.step=0;
q.push(start);
vis[start.x][start.y]=1;
while(!q.empty()){
start = q.front();
if(start.x==x2&&start.y==y2)break;
q.pop();
//2,1
temp.x=start.x+2;temp.y=start.y+1;
if(temp.x<='h'&&temp.y<=8&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//2,-1
temp.x=start.x+2;temp.y=start.y-1;
if(temp.x<='h'&&temp.y>0&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//-2,1
temp.x=start.x-2;temp.y=start.y+1;
if(temp.x>='a'&&temp.y<=8&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//-2,-1
temp.x=start.x-2;temp.y=start.y-1;
if(temp.x>='a'&&temp.y>=1&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//1,2
temp.x=start.x+1;temp.y=start.y+2;
if(temp.x<='h'&&temp.y<=8&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//1,-2
temp.x=start.x+1;temp.y=start.y-2;
if(temp.x<='h'&&temp.y>0&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//-1,2
temp.x=start.x-1;temp.y=start.y+2;
if(temp.x>='a'&&temp.y<=8&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
//-1,-2
temp.x=start.x-1;temp.y=start.y-2;
if(temp.x>='a'&&temp.y>=1&&vis[temp.x][temp.y]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.x][temp.y]=1;
}
}
printf("To get from %c%d to %c%d takes %d knight moves.\n",x1,y1,x2,y2,q.front().step);
}
}

## A strange lift

Problem Description There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button “UP” , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button “DOWN” , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can’t go up high than N,and can’t go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button “UP”, and you’ll go up to the 4 th floor,and if you press the button “DOWN”, the lift can’t do it, because it can’t go down to the -2 th floor,as you know ,the -2 th floor isn’t exist.

Here comes the problem: when you are on floor A,and you want to go to floor B,how many times at least he has to press the button “UP” or “DOWN”?

Input The input consists of several test cases.,Each test case contains two lines.

The first line contains three integers N ,A,B( 1 <= N,A,B <= 200) which describe above,The second line consist N integers k1,k2,….kn.

A single 0 indicate the end of the input.

Output For each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can’t reach floor B,printf “-1”.

Sample Input 5 1 53 3 1 2 50

Sample Output 3

#include<bits/stdc++.h>
using namespace std;
struct node
{int lou,step;};
int main(){
int a,b,c;
queue<node> q;
node start,temp;
while(scanf("%d",&a)&&a!=0){
scanf("%d %d",&b,&c);
int floor[200]={0},vis[200]={0};
for(int i=1;i <= a;i++){
scanf("%d",&floor[i]);
vis[i]=0;
}
while(!q.empty())//清空
q.pop();
start.lou=b;start.step=0;
q.push(start);
vis[start.lou]=1;
while(!q.empty()){
start = q.front();
if(start.lou==c)break;
q.pop();
temp.lou=start.lou+floor[start.lou];
if(temp.lou<=a&&vis[temp.lou]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.lou]=1;
}
temp.lou=start.lou-floor[start.lou];
if(temp.lou>0&&vis[temp.lou]!=1){
temp.step=start.step+1;
q.push(temp);
vis[temp.lou]=1;
}
}
if(q.empty()) printf("-1\n");
else printf("%d\n",q.front().step);
}
}

## 逃离迷宫

Problem Description
给定一个m × n (m行, n列)的迷宫，迷宫中有两个位置，gloria想从迷宫的一个位置走到另外一个位置，当然迷宫中有些地方是空地，gloria可以穿越，有些地方是障碍，她必须绕行，从迷宫的一个位置，只能走到与它相邻的4个位置中,当然在行走过程中，gloria不能走到迷宫外面去。令人头痛的是，gloria是个没什么方向感的人，因此，她在行走过程中，不能转太多弯了，否则她会晕倒的。我们假定给定的两个位置都是空地，初始时，gloria所面向的方向未定，她可以选择4个方向的任何一个出发，而不算成一次转弯。gloria能从一个位置走到另外一个位置吗？

Input
第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数，接下来为t组测试数据，每组测试数据中，
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数，接下来m行，每行包括n个字符，其中字符’.’表示该位置为空地，字符’*’表示该位置为障碍，输入数据中只有这两种字符，每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数，(x1, y1), (x2, y2)表示两个位置，其中x1，x2对应列，y1, y2对应行。

Output
每组测试数据对应为一行，若gloria能从一个位置走到另外一个位置，输出“yes”，否则输出“no”。

Sample Input
25 5…***.**………..*….1 1 1 1 35 5…***.**………..*….2 1 1 1 3

Sample Output
no yes

## 他记录走过的步数，等贴出代码之后再进行解释为什么要这么做

#include<bits/stdc++.h>
using namespace std;
struct node
{int x,y,wan,fangxiang;};
int vis[101][101];
int main(){
int x1,x2,y1,y2,k;
int a,b,c;
queue<node> q;
node start,temp;
scanf("%d",&a);
while(a--){
char map[101][101]={'\0'};
scanf("%d %d",&b,&c);
for(int i=0;i<b;i++)
scanf("%s",map[i]);
scanf("%d %d %d %d %d",&k,&y1,&x1,&y2,&x2);
if(x1==x2&&y1==y2){
printf("yes\n");
continue;
}
while (!q.empty())
q.pop();
memset(vis,0,sizeof(vis));
start.x=x1-1;
start.y=y1-1;
start.wan=0;
start.fangxiang=0;
vis[start.x][start.y]=1;
q.push(start);
while(!q.empty()){
start=q.front();
if(start.x==x2-1&&start.y==y2-1&&start.wan<=k+1)break;
q.pop();
//向上
temp.x=start.x+1;temp.y=start.y;
if(start.fangxiang==1)temp.wan=start.wan;
else temp.wan=start.wan+1;
if((vis[temp.x][temp.y]==0||vis[temp.x][temp.y]>=temp.wan)&&temp.x<b&&map[temp.x][temp.y]=='.'&&start.wan<=k+1){
//printf("up temp.x:%d     temp.y:%d\n",temp.x,temp.y);
if(start.fangxiang==1){
temp.fangxiang=1;
temp.wan=start.wan;
}
else{
temp.fangxiang=1;
temp.wan=start.wan+1;
}
vis[temp.x][temp.y]=temp.wan;
//printf("turn:%d\n",temp.wan);
q.push(temp);
}

//向右
temp.x=start.x;temp.y=start.y+1;
if(start.fangxiang==2)temp.wan=start.wan;
else temp.wan=start.wan+1;
if((vis[temp.x][temp.y]==0||vis[temp.x][temp.y]>=temp.wan)&&temp.y<c&&map[temp.x][temp.y]=='.'&&start.wan<=k+1){
//printf("right temp.x:%d     temp.y:%d\n",temp.x,temp.y);
if(start.fangxiang==2){
temp.fangxiang=2;
temp.wan=start.wan;
}
else{
temp.fangxiang=2;
temp.wan=start.wan+1;
}
vis[temp.x][temp.y]=temp.wan;
//printf("turn:%d\n",temp.wan);
q.push(temp);
}

//向下
temp.x=start.x-1;temp.y=start.y;
if(start.fangxiang==3)temp.wan=start.wan;
else temp.wan=start.wan+1;
if(temp.x>=0&&(vis[temp.x][temp.y]==0||vis[temp.x][temp.y]>=temp.wan)&&map[temp.x][temp.y]=='.'&&start.wan<=k+1){
//printf("down\n");
if(start.fangxiang==3){
temp.fangxiang=3;
temp.wan=start.wan;
}
else{
temp.fangxiang=3;
temp.wan=start.wan+1;
}
vis[temp.x][temp.y]=temp.wan;
//printf("turn:%d\n",temp.wan);
q.push(temp);
}

//向左
temp.x=start.x;temp.y=start.y-1;
if(start.fangxiang==4)temp.wan=start.wan;
else temp.wan=start.wan+1;
if(temp.y>=0&&(vis[temp.x][temp.y]==0||vis[temp.x][temp.y]>=temp.wan)&&map[temp.x][temp.y]=='.'&&start.wan<=k+1){
//printf("left\n");
if(start.fangxiang==4){
temp.fangxiang=4;
temp.wan=start.wan;
}
else{
temp.fangxiang=4;
temp.wan=start.wan+1;
}
vis[temp.x][temp.y]=temp.wan;
q.push(temp);
}
}
if(q.empty()){
printf("no\n");
}
else
printf("yes\n");
}
}

## Ignatius and the Princess I

Problem Description The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166’s castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrinth is a N*M two-dimensional array which left-top corner is (0,0) and right-bottom corner is (N-1,M-1). Ignatius enters at (0,0), and the door to feng5166’s room is at (N-1,M-1), that is our target. There are some monsters in the castle, if Ignatius meet them, he has to kill them. Here is some rules:

1.Ignatius can only move in four directions(up, down, left, right), one step per second. A step is defined as follow: if current position is (x,y), after a step, Ignatius can only stand on (x-1,y), (x+1,y), (x,y-1) or (x,y+1).

2.The array is marked with some characters and numbers. We define them like this:

. : The place where Ignatius can walk on.

X : The place is a trap, Ignatius should not walk on it.

n : Here is a monster with n HP(1<=n<=9), if Ignatius walk on it, it takes him n seconds to kill the monster.

Your task is to give out the path which costs minimum seconds for Ignatius to reach target position. You may assume that the start position and the target position will never be a trap, and there will never be a monster at the start position.

Input The input contains several test cases. Each test case starts with a line contains two numbers N and M(2<=N<=100,2<=M<=100) which indicate the size of the labyrinth. Then a N*M two-dimensional array follows, which describe the whole labyrinth. The input is terminated by the end of file. More details in the Sample Input.

Output For each test case, you should output “God please help our poor hero.” if Ignatius can’t reach the target position, or you should output “It takes n seconds to reach the target position, let me show you the way.”(n is the minimum seconds), and tell our hero the whole path. Output a line contains “FINISH” after each test case. If there are more than one path, any one is OK in this problem. More details in the Sample Output.

Sample Input 5 6.XX.1…X.2.2…X….XX.XXXXX.5 6.XX.1…X.2.2…X….XX.XXXXX15 6.XX…..XX1.2…X….XX.XXXXX.

Sample Output It takes 13 seconds to reach the target position, let me show you the way.1s:(0,0)->(1,0)2s:(1,0)->(1,1)3s:(1,1)->(2,1)4s:(2,1)->(2,2)5s:(2,2)->(2,3)6s:(2,3)->(1,3)7s:(1,3)->(1,4)8s:FIGHT AT (1,4)9s:FIGHT AT (1,4)10s:(1,4)->(1,5)11s:(1,5)->(2,5)12s:(2,5)->(3,5)13s:(3,5)->(4,5)FINISHIt takes 14 seconds to reach the target position, let me show you the way.1s:(0,0)->(1,0)2s:(1,0)->(1,1)3s:(1,1)->(2,1)4s:(2,1)->(2,2)5s:(2,2)->(2,3)6s:(2,3)->(1,3)7s:(1,3)->(1,4)8s:FIGHT AT (1,4)9s:FIGHT AT (1,4)10s:(1,4)->(1,5)11s:(1,5)->(2,5)12s:(2,5)->(3,5)13s:(3,5)->(4,5)14s:FIGHT AT (4,5)FINISHGod please help our poor hero.FINISH

#include<bits/stdc++.h>
using namespace std;
struct node
{int x,y,time;};
int vis[120][120];
int a,b;
int turn[4][2]={0,1,1,0,0,-1,-1,0};
node start,temp;
bool check(int x,int y,int z){
if(x>=0&&y>=0&&x<a&&y<b&&(vis[x][y]==0||vis[x][y]>z))
return true;
return false;
}
int main(){
node roate[120][120];
int i;
while(~scanf("%d %d",&a,&b)){
memset(roate,0,sizeof(roate));
char Map[120][120]={'\0'};
memset(Map,0,sizeof(Map));
memset(vis,0,sizeof(vis));
for(i=0;i<a;i++){
scanf("%s",&Map[i]);
}
queue<node> q;
while(!q.empty())
q.pop();
start.x=0;
start.y=0;
start.time=0;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
for(i=0;i<4;i++){
temp.x=turn[i][0]+start.x;
temp.y=turn[i][1]+start.y;
if(Map[temp.x][temp.y]=='.')
temp.time=start.time+1;
if(Map[temp.x][temp.y]<='9'&&Map[temp.x][temp.y]>='1')
temp.time=start.time+Map[temp.x][temp.y]-'0'+1;
if(Map[temp.x][temp.y]=='.'&&check(temp.x,temp.y,temp.time)){
vis[temp.x][temp.y]=temp.time;
q.push(temp);
roate[temp.x][temp.y]=start;
}
if(Map[temp.x][temp.y]<='9'&&Map[temp.x][temp.y]>='1'&&check(temp.x,temp.y,temp.time)){
vis[temp.x][temp.y]=temp.time;
q.push(temp);
roate[temp.x][temp.y]=start;
}
}
}
if(vis[a-1][b-1]==0)
printf("God please help our poor hero.\n");
else{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",vis[a-1][b-1]);
stack<node>v;
while(!v.empty())
v.pop();
start.x=a-1;start.y=b-1;start.time=vis[a-1][b-1];
while(!(start.x==0&&start.y==0)){
v.push(start);
start = roate[start.x][start.y];
}
start.x=0,start.y=0,start.time=0;
v.push(start);int flag=1;
while(!(v.top().x==a-1&&v.top().y==b-1)){
int time1=v.top().time;
printf("%ds:(%d,%d)->",flag,v.top().x,v.top().y);
v.pop();
printf("(%d,%d)\n",v.top().x,v.top().y);
flag++;
int lzk=0;
while(v.top().time-time1-lzk!=1){
printf("%ds:FIGHT AT (%d,%d)\n",flag,v.top().x,v.top().y);
flag++;lzk++;
}
}
}printf("FINISH\n");
}
}

## 诡异的楼梯

原文作者：BFS
原文地址: https://blog.csdn.net/Loser_Peter/article/details/80258321
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。