小结一下BFS模板
(后面有单独的bfs小结)
写 一下做BFS 的思路。因为这题比较简单,代码量相对较少,也容易理解一些 更容易总结出模板
1、
先定义有关变量,一般是一个边界值、一个初始值、一个标记数组、加上一个 数组(一个变量) pair<>类型 (两个变量,如 x,y 坐标类型) 或 struct 定义一个新的类(三个以上变量)
2.
按照题意先建立主函数,如果是迷宫类问题,读入的可以直接用一层for循环加 %s 字符串,如果用两层for循环加 %c 字符的话要记得加getchar()
3.
最好bfs不要定义成int型,容易出现BUG(都是泪)。结果传递的时候注意 边界判断的 if 的位置,一般在while( q.size() )循环里 for()循环外。也不排除在for里面。
4.
到了最关键的bfs函数部分(……),bfs是宽度/广度搜索的简称,所以和dfs比起来,它有限搜索所有子节点,再搜索孙节点,以此类推。
在运用的时候一般是 队列/优先队列 + 一个模拟用的for + 一个判断用的judge(可以写在里面)来构成(如果用优先队列的话要记得重构)。
5.
运用时:先用for模拟所有的可能,然后判断是否加入队列,如果不符合,就自动进入下一个队列元素的循环(循环开始时该元素在队列中已经删除)。
否则的话就把该元素加入队列,并把计数数组vis加一。
6.
直到找到了ed(结束值)或者队列为空,循环结束。
——————————————————————————————————————————————-——
Catch That Cow
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12305 Accepted Submission(s): 3823
Problem Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
- Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
- Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Line 1: Two space-separated integers: N and K
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
5 17
Sample Output
4
HintThe fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
Source
USACO 2007 Open Silver
Recommend
teddy | We have carefully selected several similar problems for you: 2102 1372 1240 1072 1180
————————————————————————————————————————————————
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAX_N = 1e5+11;
int st,ed;
int vis[MAX_N*2];
int d[MAX_N*2];
/*
*/
void bfs(int x)
{
int nx;
vis[x] = 1;
d[x] = 0;
queue<int>q;
q.push(x);
while( q.size() )
{
int s=q.front();
q.pop();
for(int i=1; i<=3; i++ )
{
if( i == 1 )
{
nx = s+1;
}
else if( i == 2 )
{
nx = s-1;
}
else
{
nx = s*2;
}
if( !vis[nx] && nx<=MAX_N && nx>=0 )
{
vis[nx] = 1;
q.push(nx);
d[nx] = d[s]+1;
}
if( nx == ed )
{
printf("%d\n",d[nx]);
return;
}
}
}
}
int main()
{
while( ~scanf("%d%d",&st,&ed))
{
memset(vis, 0, sizeof(vis)); //一定要用 memset 别老用for循环清零 一个是麻烦,第二是容易错
memset(d, 0, sizeof(d));
if( st == ed )
{
printf("0\n");
continue;
}
bfs(st);
}
return 0;
}
/*
下面附上白皮书上的通用迷宫模板(略典型,思想还是一样的)
已经加好了注释:
const int INF = 0x3f3f3f; //没有到达的地方都是无穷大
typedef pair<int,int> P; //如果量多了可以改成类
char maze[MAX_N][MAX_N+1]; // 存储字符
int N,M;
int sx,sy; //开始坐标
int gx,gy; //结束坐标
int d[MAX_N][MAX_N]; //记录走的步数
int dx[4] = {1,0,-1,0}; //上下左右行走的模拟
int dy[4] = {0,1,0,-1};
int 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; //并把该点的距离设置为0;
while( que.front() ){ //判断队列是否为空
p = que.front(); //把队列的第一个值给 p ;
que.pop(); // 移除
if(P.first == gy && P.second == gy)break;
//如果是到了终点直接退出
for(int 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){
que.push(P(nx,ny));
d[nx][ny] = d[P.first][P.second] + 1;
}
}
}
}
void solve(){
int res = bfs();
printf("%d\n",res);
}
*/