bfs广搜题目加部分解释
这里是我做过的一部分广搜的题目,写下是为了以后能够回顾。
第一题 Catch That Cow POJ 3278
题目链接
这道题的大致意思是给你两个数a,b。然后让你将a进行以下操作:1.a+1;2.a-1;3.x*a。问你a做上述操作最小几步能够变成b。
思路,一开始做这道题的时候我不知道它怎么会和bfs扯上关系的,然后问了一下旁边的大佬原来是将a变化出来的数字记录下来,然后一步一步去推,想出这一点,这道题就是bfs的入门题了。
具体代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 200005;
int map[maxn];
int n, m;
int ans;
struct node{
int x;
int p;
} st;
bool ok(int x){
if(x<0||x>100000)
return false;
else if(map[x])
return false;
else if(!map[x])
return true;
}
void bfs(int x){
queue<node> q;
q.push(st);
while(!q.empty()){
node t=q.front();
if(t.x==m){
ans = t.p;
break;
}
q.pop();
node e;
int fx = t.x + 1;
int fy = t.x - 1;
int fz = t.x * 2;
if(ok(fx)){
e.x = fx;
e.p = t.p + 1;
map[fx] = 1;
q.push(e);
}
if(ok(fy)){
e.x = fy;
e.p = t.p + 1;
map[fy] = 1;
q.push(e);
}
if(ok(fz)){
e.x = fz;
e.p = t.p + 1;
map[fz] = 1;
q.push(e);
}
}
}
int main(){
scanf("%d%d", &n, &m);
st.x = n;
st.p = 0;
ans = 0;
memset(map, 0, sizeof map);
map[n] = 1;
bfs(n);
printf("%d\n", ans);
}
第二题 Dungeon Master POJ 2251
题目链接
这道题的大致意思就是给你一个一共有n层每层m*k大小的迷宫,入口在S处,出口在E处,每移动1格需要浪费,‘#’是不可以走的,‘.’是可以走的。问你是否能逃出,如果能逃出需要耗费多少时间。
这道题不同于我平时做的bfs题,平时做的bfs一般是2维的,这道题是三维,可是做法是一样的,只要将移动数组改为{{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}就可以了,做法和二维一样。
具体代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 40;
char ah[maxn][maxn][maxn];
int map[maxn][maxn][maxn];
int l, r, c;
int ans;
int moved[10][5] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
struct node{
int x;
int y;
int z;
int p;
}st;
bool ok(int x,int y,int z){
if(x<1||x>l||y<1||y>r||z<1||z>c){
return false;
}
else if(map[x][y][z]==0)
return true;
else if(map[x][y][z]==1)
return false;
}
bool bfs(int x,int y,int z){
queue<node> q;
q.push(st);
int flag = 0;
while(!q.empty()){
node t = q.front();
q.pop();
if(ah[t.x][t.y][t.z]=='E'){
ans = t.p;
return true;
}
for (int i = 0; i < 6;i++){
int fx = t.x + moved[i][0];
int fy = t.y + moved[i][1];
int fz = t.z + moved[i][2];
if(ok(fx,fy,fz)){
node f;
f.x = fx;
f.y = fy;
f.z = fz;
f.p = t.p + 1;
q.push(f);
map[fx][fy][fz] = 1;
}
}
}
return false;
}
int main(){
while(scanf("%d%d%d", &l, &r, &c)&&l&&r&&c)
{
for (int i = 1; i <= l;i++){
for (int j = 1; j <= r;j++){
scanf("%s", ah[i][j] + 1);
}
}
for (int i = 1; i <= l;i++){
for (int j = 1; j <= r;j++){
for (int k = 1; k <= c;k++){
if(ah[i][j][k]=='S'){
st.x = i;
st.y = j;
st.z = k;
st.p = 0;
}
else if(ah[i][j][k]=='.'||ah[i][j][k]=='E'){
map[i][j][k] = 0;
}
else if(ah[i][j][k]=='#')
map[i][j][k] = 1;
}
}
}
if(bfs(st.x, st.y, st.z))
printf("Escaped in %d minute(s).\n", ans);
else
printf("Trapped!\n");
}
}
第三题 Asteroids! HDU 1240
题目链接
这道题的大致意思和上面一题是差不多的,给你一个N层每层N*N大小的平面,然后给你个起点和终点,‘X’是不能走的,‘o’是可以走的。问你是否能从起点走到终点,如果能要走几步。
这道题和上一题基本是一模一样的,只是题面,输入,输出换了,做法是一模一样的,都是三维中用bfs搜索。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 15;
char sta[10];
char end1[10];
char map[maxn][maxn][maxn];
int dp[maxn][maxn][maxn];
int moved[10][5] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
int n;int ans;
struct node{
int x, y, z;
int s;
}st,en;
bool ok(int x,int y,int z){
if(x>=n||x<0||y>=n||y<0||z>=n||z<0)
return false;
else if(dp[x][y][z])
return false;
else
return true;
}
bool bfs(){
queue<node> q;
q.push(st);
while(!q.empty()){
node t = q.front();
q.pop();
if(t.x==en.x&&t.y==en.y&&t.z==en.z){
ans = t.s;
return true;
}
for (int i = 0; i < 6;i++){
int fx = t.x + moved[i][0];
int fy = t.y + moved[i][1];
int fz = t.z + moved[i][2];
if(ok(fx,fy,fz)){
node e;
e.x = fx;
e.y = fy;
e.z = fz;
e.s = t.s + 1;
dp[fx][fy][fz] = 1;
q.push(e);
}
}
}
return false;
}
int main(){
while(~scanf("%s%d",sta,&n)){
for (int i = 0;i<n;i++){
for (int j = 0;j<n;j++){
scanf("%s", map[i][j] );
}
}
for (int i = 0;i<n;i++){
for (int j = 0; j < n;j++){
for (int k = 0; k < n;k++){
if(map[i][j][k]=='X')
dp[i][j][k] = 1;
else
dp[i][j][k] = 0;
}
}
}
scanf("%d%d%d", &st.z, &st.y, &st.x);
dp[st.x][st.y][st.z] = 1;
scanf("%d%d%d", &en.z, &en.y, &en.x);
st.s = 0;
ans = 0;
scanf("%s", end1);
if(bfs())
printf("%d %d\n", n, ans);
else
printf("NO ROUTE\n");
}
}