acwing提高——BFS的Flood Fill和最短路模型

Flood Fill

1.Lake Counting

题目http://ybt.ssoier.cn:8088/problem_show.php?pid=1249

 自己写的(好理解)

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=120;
int n,m;
char a[N][N];
bool st[N][N];
int sum;
int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
void bfs(int x,int y)
{
	st[x][y]=true;
	for(int i=0;i<4;i++)
	{
		int xx=dx[i]+x,yy=dy[i]+y;
		if(a[xx][yy]=='W'&&!st[xx][yy])
		bfs(xx,yy);
	}
}
void solve()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(a[i][j]=='W'&&!st[i][j])
			{
				sum++;
				bfs(i,j);
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	cin>>a[i][j];
	solve();
	cout<<sum;
} 

y总的 (标准)(手写队列)

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> pii;
const int N=115;
int n,m,cnt=0;
char g[N][N];
bool st[N][N];
pii q[N*N];
void bfs(int sx,int sy)
{
    int hh=0,tt=0;
    q[0]={sx,sy};
    st[sx][sy]=true;
    while(hh<=tt)
    {
        auto t=q[hh++];
        for(int i=t.x-1;i<=t.x+1;i++)//因为求八个周围的,则循环枚举两层即可
            for(int j=t.y-1;j<=t.y+1;j++)
            {
               if(i<0||i>=n||j<0||j>=m) continue;//假如越界则continue
               if(st[i][j]) continue;//假如标记过则continue
               if(g[i][j]=='.') continue;//假如是干燥的则continue
               st[i][j]=true;//标记这个点被标记过
               q[++tt]={i,j};//把这个积水放进队列用,以后用他来更新其他的积水
            }
    }
}
int main()
{
  cin>>n>>m;
  for(int i=0;i<n;i++) cin>>g[i];
  for(int i=0;i<n;i++)//遍历每一个点
    for(int j=0;j<m;j++)
      if(!st[i][j]&&g[i][j]=='W')//假如之前没标记过并且是新的水洼
      {
          bfs(i,j);//遍历这个水洼覆盖的水洼
          cnt++;//水洼数量加一
      }
  cout<<cnt<<endl;
   return 0;
}

 2.The Castle(城堡问题)

题目 http://ybt.ssoier.cn:8088/problem_show.php?pid=1250

 

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
const int N=55;
int  g[N][N];
bool st[N][N];
PII q[N*N];
int n,m;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
int bfs(int x,int y)
{
	int hh=0,tt=0;
	int area=0;
	q[0]={x,y};
	st[x][y]=true;
	while(hh<=tt)
	{
		PII t=q[hh++];
		area++;
		for(int i=0;i<4;i++)
		{
			int a=t.x+dx[i],b=t.y+dy[i];
			if(a<0||a>=n||b<0||b>=m)continue;
			if(st[a][b])continue;
			if((g[t.x][t.y]>>i) & 1)continue;//判断该方向上 边有没有墙
			q[++tt]= {a,b};
			st[a][b]=true;
		}
		
	}
	return area;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	cin>>g[i][j];
	int cnt=0,area=0;
	for(int i=0;i<n;i++)
	for(int j=0;j<m;j++)
	{
		if(!st[i][j])
		{
			area=max(area,bfs(i,j));
			cnt++;
		}
	}

	cout<<cnt<<endl<<area;
}

3.山峰和山谷

题目http://ybt.ssoier.cn:8088/problem_show.php?pid=1454

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
const int N=1010;
int  h[N][N];
bool st[N][N];
PII q[N*N];
int n;

int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
void bfs(int x,int y,bool &has_higher,bool &has_lower)
{
	int hh=0,tt=0;
	q[hh]={x,y};
	st[x][y]=true;
	while(hh<=tt)
	{
		PII t=q[hh++];
		for(int i=0;i<8;i++)
		{
			int xx=t.x+dx[i],yy=t.y+dy[i];
			if(xx<=0||xx>n||yy<=0||yy>n)continue;
	
			if(h[xx][yy]>h[t.x][t.y])
			has_higher=true;
			else if(h[xx][yy]<h[t.x][t.y])
			has_lower=true;
			else if(!st[xx][yy])
			{
				st[xx][yy]=true;
				q[++tt]={xx,yy};
			}
		}
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	cin>>h[i][j];
	int peak=0,valley=0;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(!st[i][j])
		{
			bool has_higher=false,has_lower=false;
			bfs(i,j,has_higher,has_lower);
			if(!has_higher)peak++;
			if(!has_lower)valley++;
		}
	} 
	cout<<peak<<" "<<valley;
}

最短路模型 

1.迷宫问题

题目 icon-default.png?t=N4HBhttp://ybt.ssoier.cn:8088/problem_show.php?pid=1255

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;

const int N=10;
int n;
int g[N][N];
PII q[N*N];
PII pre[N][N];
bool st[N][N];
int dx[]={-1,0,1,0},dy[]={0,-1,0,1};
void bfs(int x,int y)
{
	int hh=0,tt=0;
	q[0]={x,y};
	st[x][y]=true;
	pre[x][y]={0,0};
	while(hh<=tt)
	{
		PII t=q[hh++];
		for(int i=0;i<4;i++)
		{
			int xx=t.x+dx[i],yy=t.y+dy[i];
			if(xx<0||xx>=n||yy<0||yy>=n)continue;
			if(st[xx][yy])continue;
			if(g[xx][yy])continue;
			pre[xx][yy]=t;
			q[++tt]={xx,yy};
			st[xx][yy]=true;
		}
	}
}
int main()
{
	n=5;
	for(int i=0;i<n;i++)
	for(int j=0;j<n;j++)
	cin>>g[i][j];
	bfs(n-1,n-1);
	PII end(0,0);
	while(true)
	{
		cout<<"("<<end.x<<", "<<end.y<<")"<<endl;
		if(end.x==n-1&&end.y==n-1)break;
		end=pre[end.x][end.y];
	}
}

2.武士风度的牛 

题目 icon-default.png?t=N4HBhttps://www.acwing.com/problem/content/190/

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;

const int N=160;
int n,m;
char g[N][N];
PII q[N*N];
bool st[N][N];
int dx[]={-1,-2,-2,-1,1,2,2,1},dy[]={-2,-1,1,2,2,1,-1,-2};
int dist[N][N];
void bfs(int x,int y)
{
	int hh=0,tt=0;
	q[0]={x,y};
	st[x][y]=true;
	dist[x][y]=0;
	while(hh<=tt)
	{
		PII t=q[hh++];
		for(int i=0;i<8;i++)
		{
			int xx=t.x+dx[i],yy=t.y+dy[i];
			if(xx<0||xx>=m||yy<0||yy>=n)continue;
			if(st[xx][yy])continue;
			if(g[xx][yy]=='*')continue;
			dist[xx][yy]=dist[t.x][t.y]+1;
			q[++tt]={xx,yy};
			st[xx][yy]=true;
		}
	}
}
int main()
{
	cin>>n>>m;
	int sx,sy,ex,ey;
	for(int i=0;i<m;i++)
	for(int j=0;j<n;j++)
	{
		cin>>g[i][j];
		if(g[i][j]=='K')sx=i,sy=j;
		if(g[i][j]=='H')ex=i,ey=j; 
	}
	bfs(sx,sy);
	cout<<dist[ex][ey];
}

3.抓住那头牛

题目 icon-default.png?t=N4HBhttp://ybt.ssoier.cn:8088/problem_show.php?pid=1253

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,k;
int dist[N];//记录每个点到起点的步数
int q[N];
int bfs()
{
    int hh=0,tt=0;
    q[0]=n;
    memset(dist,-1,sizeof dist);
    dist[n]=0;
    while(hh<=tt)
    {
        int t=q[hh++];
        if(t==k) return dist[k];//返回到起点的步数
        if(t+1<N&&dist[t+1]==-1)//第一种情况走,且该位置没有被走过
        {
            dist[t+1]=dist[t]+1;//则该点距离+1
            q[++tt]=t+1;//将该点放进队列中
        }
        if(t-1>=0&&dist[t-1]==-1)//第二种情况走,且该位置没有被走过
        {
            dist[t-1]=dist[t]+1;//则该点距离+1
            q[++tt]=t-1;//将该点放进队列中
        }
        if(2*t<N&&dist[2*t]==-1)//第三种情况走,且该位置没有被走过
        {
            dist[2*t]=dist[t]+1;//则该点距离+1
            q[++tt]=2*t;//将该点放进队列中
        }
    }
    return 0;
}
int main()
{
   cin>>n>>k;
   cout<<bfs()<<endl;//输出最小步数
   return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值