1.油田连通块
链接地址:地址
递归DFS
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char map[110][110];
bool vis[110][110]={0};//布尔类型减少内存浪费
int orient[8][2]={1,1,1,0,1,-1,0,1,0,-1,-1,1,-1,0,-1,-1};
//八个方向的遍历
int m,n;
void DFS(int x,int y)
{
if(x<0||x>=m||y<0||y>=n)
return ;
if(vis[x][y]==1||map[x][y]!='@')
return ;
vis[x][y]=1;
for(int i=0;i<8;i++)
{
DFS(x+orient[i][0],y+orient[i][1]);
}
}
int main()
{
while(scanf("%d%d",&m,&n)&&m!=0)
{
memset(vis,0,sizeof(vis));
int count=0;
for(int i=0;i<m;i++)
scanf("%s",map[i]);
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(vis[i][j]==0&&map[i][j]=='@')
{
DFS(i,j);
count++;//计数器
}
}
printf("%d\n",count);//不用cout没有追求代码速度,而是追求运行速度
}
return 0;
}
2.Knight Moves
链接地址:链接
单向BFS
a.有返回值类型
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
//单向BFS实现,注意队列的使用
bool vis[310][310]={0};
int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}};
int l;
typedef struct node
{
int x,y,step;
}node;
bool check(int x,int y)
{
if(x<0||x>=l||y<0||y>=l)
return false;
return true;
}
int BFS(int x1,int y1,int x2,int y2)
{
queue<node>Q;//注意队列的清空
node temp;
temp.x=x1,temp.y=y1,temp.step=0;
Q.push(temp);
vis[x1][y1]=1;
while(!Q.empty())
{
temp=Q.front();
Q.pop();
if(temp.x==x2&&temp.y==y2)//判断弹出条件
return temp.step;
for(int i=0;i<8;i++)
{
node Next;
Next.x=temp.x+orient[i][0];
Next.y=temp.y+orient[i][1];
Next.step=temp.step+1;
if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0)
{
vis[Next.x][Next.y]=1;
Q.push(Next);
}
}
}
return 0;//欺骗函数的返回,摆设
}
int main()
{
int t,x1,y1,x2,y2;
cin>>t;
while(t--)
{
cin>>l;
cin>>x1>>y1>>x2>>y2;
memset(vis,0,sizeof(vis));
printf("%d\n",BFS(x1,y1,x2,y2));
}
return 0;
}
b.无返回值类型
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
bool vis[310][310]={0};
int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}};
int l;
typedef struct node
{
int x,y,step;
}node;
bool check(int x,int y)
{
if(x<0||x>=l||y<0||y>=l)
return false;
return true;
}
void BFS(int x1,int y1,int x2,int y2)
{
queue<node>Q;
node temp;
temp.x=x1,temp.y=y1,temp.step=0;
Q.push(temp);
vis[x1][y1]=1;
while(!Q.empty())
{
temp=Q.front();
Q.pop();
if(temp.x==x2&&temp.y==y2)
{
printf("%d\n",temp.step);//直接进行输出会节省时间
}
for(int i=0;i<8;i++)
{
node Next;
Next.x=temp.x+orient[i][0];
Next.y=temp.y+orient[i][1];
Next.step=temp.step+1;
if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0)
{
vis[Next.x][Next.y]=1;
Q.push(Next);
}
}
}
//return 0;
}
int main()
{
int t,x1,y1,x2,y2;
cin>>t;
while(t--)
{
cin>>l;
cin>>x1>>y1>>x2>>y2;
memset(vis,0,sizeof(vis));
BFS(x1,y1,x2,y2);
}
return 0;
}
双向BFS
#include <iostream>
#include<algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
const int N = 310;
int l;
int vis[N][N];
int dis[N][N];
int orient[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1},{-1,2},{-1,-2}};
typedef struct node
{
int x,y;
}node;
void dBFS(int x1,int y1,int x2,int y2)
{
if(x1==x2&&y1==y2)//注意相等条件的弹出
{
printf("0\n");
return ;
}
queue<node>Q;
node front,behind;//用front,behind是为了复习的时候好理解
front.x=x1,front.y=y1;
behind.x=x2,behind.y=y2;
vis[x1][y1]=1;//从头开始的标记1
vis[x2][y2]=2;//从尾开始的标记2
Q.push(front);
Q.push(behind);
while(!Q.empty())
{
front=Q.front();
Q.pop();//注意每次的弹出
for(int i=0;i<8;i++)
{
behind.x=front.x+orient[i][0];
behind.y=front.y+orient[i][1];
if(behind.x>=0&&behind.x<l&&behind.y>=0&&behind.y<l)//当吧判断条件写成这样可以减少
{ //进入函数所浪费的时间
if(!vis[behind.x][behind.y])
{
vis[behind.x][behind.y]=vis[front.x][front.y];
dis[behind.x][behind.y]=dis[front.x][front.y]+1;//距离加1,因为队列是
Q.push(behind); //先进先出所以是BFS
}
else if(vis[behind.x][behind.y]!=vis[front.x][front.y])//最短路径优先输出
{
printf("%d\n",dis[front.x][front.y]+dis[behind.x][behind.y]+1);//相遇时少了一步
return;
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
int x1,y1,x2,y2;
scanf("%d%d%d%d%d",&l,&x1,&y1,&x2,&y2);
dBFS(x1,y1,x2,y2);
}
return 0;
}
3.Red and Black
求定点连通块,直接DFS
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char map[30][30];
bool vis[30][30];
int w,h,step;
int orient[4][2]={1,0,0,1,-1,0,0,-1};
struct position
{
int x,y;
};
void DFS(int x,int y)
{
if(x<0||x>=h||y<0||y>=w||map[x][y]=='#')
return ;
if(vis[x][y]!=0)//发现不能用非,一个符号卡了我半小时
return;
vis[x][y]=1;
step=step+1;//计数器
for(int i=0;i<4;i++)
{
DFS(x+orient[i][0],y+orient[i][1]);
}
}
int main()
{
while(~scanf("%d%d",&w,&h)&&(w*h)!=0)
{
step=0;
position person;
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
for(int i=0;i<h;i++)
{
getchar();//吸掉每次换行的回车,包括第一次输入w,h
for(int j=0;j<w;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='@')
{
person.y=i,person.x=j;//记录人的位置
//vis[i][j]=1;
}
}
}
DFS(person.y,person.x);
printf("%d\n",step);
}
return 0;
}
来源:CSDN
作者:WarYan
链接:https://blog.csdn.net/weixin_45628245/article/details/103460986