由于深搜过于复杂(。。我蒟蒻),于是从广搜写起。。
话不多说,上代码
hdu 1312
踩地板问题,用广搜从题中定义方向开始搜索,逐一标记即可。
bfs入门题
#include <bits/stdc++.h>
using namespace std;
char room[30][30];
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//每次搜索查找的范围。
int wx,wy,num;
#define CHECK(x,y)(x<wx&&x>=0&&y<wy&&y>=0)//比定义一个函数调用起来更快。
struct node{int x,y;};//定义结构体来存坐标。
void bfs(int dx,int dy){
num=1;
queue<node>q;//用对列来记录可以搜索的位置。
node start,next;//用两个名字分别记录位置。
start.x=dx;//记录起始位置。
start.y=dy;
q.push(start);//先将起始位置存入队列里面。
while(!q.empty()){//逐一检验队列储存位置是否能拓展。
start=q.front();
q.pop();//将将要检验的位置出队列。
for(int i=0;i<4;i++){
next.x=start.x+dir[i][0];//记录下一步的位置。
next.y=start.y+dir[i][1];
if(CHECK(next.x,next.y)&&room[next.x][next.y]=='.'){
num++;
room[next.x][next.y]='#';//将’走‘过的路做标记。
q.push(next);//进队列。
}
}
}
}
int main()
{
int x,y,dx,dy;
while(cin>>wx>>wy){
if(wx==0&&wy==0)break;
for(int i=0;i<wy;i++){
for(int j=0;j<wx;j++){
cin>>room[j][i];
if(room[j][i]=='@'){
dx=j;dy=i;//记录起始位置。
}
}
}
num=0;
bfs(dx,dy);
cout<<num<<endl;
}
return 0;
}
再来一道入门题
洛谷 1443 马的遍历
更上一道题思路一样,逐一标记判断,区别在于计数方式不同。
#include <bits/stdc++.h>
#define CHECK(y,x) (x>=1&&x<=wx&&y>=1&&y<=wy)//迷。。
using namespace std;
int map1[405][405];//定义一个棋盘。
int wx,wy;//wx是棋盘的列数,wy是棋盘的行数。
struct node{int x,y;};//用结构体来记录每次广搜的坐标。
int dir[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};//标记马行走方位。
void bfs(int x,int y){
node start,next;//用两个结构体变量来记录位置。
memset(map1,-1,sizeof(map1));//标记未到达位置。
start.x=x;start.y=y;
queue<node>q;
q.push(start);
map1[start.x][start.y]=0;//记录步骤。
while(!q.empty()){
start=q.front();
q.pop();
for(int i=0;i<8;i++){
next.x=start.x+dir[i][0];
next.y=start.y+dir[i][1];
if(CHECK(next.x,next.y)&&map1[next.x][next.y]==-1){
map1[next.x][next.y]=map1[start.x][start.y]+1;//记录所用步骤。
q.push(next);//存放新坐标。
}}
}
}
int main()
{ int x,y;
while(cin>>wy>>wx>>x>>y){//wy是行数,wx是列数。
bfs(x,y);
for(int i=1;i<=wy;i++)
for(int j=1;j<=wx;j++)
j!=wx?printf("%-5d",map1[i][j]):printf("%-5d\n",map1[i][j]);}
return 0;
}
再来一道类似的(愉快水题)
洛谷 1596 USACO
bfs+标记
#include <bits/stdc++.h>
#define CHECK(y,x) (x<dx&&x>=0&&y>=0&&y<dy)
using namespace std;
struct node{int x,y;};
int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}};
char map1[101][101];
int dx,dy,num=0;
void bfs(int y,int x)
{
queue<node>q;
node start,next;
start.x=x;start.y=y;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
for(int i=0;i<8;i++)
{
next.x=start.x+dir[i][0];
next.y=start.y+dir[i][1];
if(CHECK(next.y,next.x)&&map1[next.y][next.x]=='W')
{
q.push(next);
map1[next.y][next.x]='.';
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin>>dy>>dx;
int x,y;
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
cin>>map1[i][j];
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
if(map1[i][j]=='W'){
bfs(i,j);
num++;}
cout<<num<<endl;
return 0;
}
搜索
也是入门题。
#include <bits/stdc++.h>
using namespace std;
#define CHECK(y,x) (x>=0&&x<4&&y>=0&&y<4)
char a[5][5];
int falg;
struct node{int x,y;};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void bfs(int y,int x){
queue<node>q;
falg=0;
node start,next;
start.x=x;start.y=y;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
for(int i=0;i<4;i++){
next.y=start.y+dir[i][0];
next.x=start.x+dir[i][1];
if(CHECK(next.y,next.x)&&a[next.y][next.x]=='#'){
q.push(next);
a[next.y][next.x]='*';}
if(next.x==3&&next.y==3){
falg=1;
break;
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
while(n--){
for(int i=0;i<4;i++)
scanf("%s",a[i]);
bfs(0,0);
if(falg)printf("YES\n");
else printf("NO\n");
}
return 0;
}
#include <bits/stdc++.h>
#define CHECK(y,x) (y>=0&&y<dy&&x>=0&&x<dx)
using namespace std;
struct node{int x,y;};
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int dx,dy,num,ans=0;
int a[101][101];
int bfs(int y,int x)
{ queue<node>q;
num=1;a[y][x]=0;
node start,next;
start.x=x;start.y=y;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
for(int i=0;i<4;i++){
next.y=start.y+dir[i][0];
next.x=start.x+dir[i][1];
if(CHECK(next.y,next.x)&&a[next.y][next.x]==1){
q.push(next);
a[next.y][next.x]=0;
num++;
}
}
}
return num;
}
int main()
{ int n;
scanf("%d %d",&dy,&dx);
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
scanf("%d",&a[i][j]);
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
if(a[i][j]==1){
n=bfs(i,j);
if(ans<n)ans=n;}
printf("%d\n",ans);
return 0;
}
#include <bits/stdc++.h>
#define CHECK(y,x) (y>=0&&y<dy&&x>=0&&x<dx)
using namespace std;
struct node{int x,y;};
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int dx,dy,num;
char a[51][51];
void bfs(int y,int x)
{ queue<node>q;
num=1;
node start,next;
start.x=x;start.y=y;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
for(int i=0;i<4;i++){
next.y=start.y+dir[i][0];
next.x=start.x+dir[i][1];
if(CHECK(next.y,next.x)&&a[next.y][next.x]=='.'){
q.push(next);
a[next.y][next.x]='#';
num++;
}
}
}
}
int main()
{ scanf("%d %d",&dx,&dy);
for(int i=0;i<dy;i++)
scanf("%s",a[i]);
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
if(a[i][j]=='@'){
bfs(i,j);
break;}
printf("%d\n",num);
return 0;
}
再写一道关于用map来优化搜索的题。。其实觉得加用string里的find()函数再标记后还能再优化。。等大佬指点
洛谷 1032
#include <bits/stdc++.h>
using namespace std;
map<string,int>m;
int ans,n,k;
string a,b;
string f[15],s[15];
struct node{string str;int step;};
string check(string str,int i,int j){//用来替换字符串和判断是否能进行替换。
string a="";
if(i+f[j].length()>str.length())return a;
for(k=0;k<f[j].length();k++)
if(str[i+k]!=f[j][k])return a;
a=str.substr(0,i);//替换字符串。
a+=s[j];
a+=str.substr(i+k);
return a;}
void bfs()
{ queue<node>q;
node start,next;
start.str=a;start.step=0;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
string temp;
if(m[start.str]==1)continue;
if(start.str==b){ans=start.step; break;}
m[start.str]=1;
for(int i=0;i<start.str.length();i++)//把每一位当做可以替换的首位来判断是否能替换。
for(int j=0;j<n;j++){//将每组逐一判断。
temp=check(start.str,i,j);
if(temp!=""){
next.str=temp;
next.step=start.step+1;
q.push(next);
}
}
}
if(ans>10||ans==0)printf("NO ANSWER!\n");
else printf("%d\n",ans);
}
int main()
{
cin>>a>>b;
while(cin>>f[n]>>s[n])
n++;
bfs();
return 0;
}
我又来写bfs了更新一道标记题
洛谷 1135 奇怪的电梯
细节有点多,优化的方式也很多。。不标记会MLE
#include <bits/stdc++.h>
#define check(n) (n>=1&&n<=h)
using namespace std;
int a[205],ans=12345,h,p,f;
struct node{int n,step;};
void bfs(){
queue<node>q;
node start,next;
start.n=f;start.step=0;
q.push(start);
while(!q.empty()){
start=q.front();
q.pop();
next.n=start.n+a[start.n];
if(check(next.n)){
next.step=start.step+1;
q.push(next);
if(next.n==p)
ans=min(ans,next.step);
}
next.n=start.n-a[start.n];
if(check(next.n)){
next.step=start.step+1;
q.push(next);
if(next.n==p)
ans=min(ans,next.step);
}
a[start.n]=12345;
}
}
int main()
{
scanf("%d %d %d",&h,&f,&p);
for(int i=1;i<=h;i++)
scanf("%d",&a[i]);
if(f==p)printf("0");
else{
bfs();
if(ans==12345)printf("-1");
else
printf("%d",ans);}
return 0;
}
(持续更新中。。)