2593 梦中岛之路(bfs)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43540515/article/details/102672450

小Y上课摸鱼睡着了,梦里,他在一座岛上,因为是梦,所以他有上帝视角,他看到另一座岛上有宝藏,但是两座岛不相连,于是乎他现在要把一些海水变成路使得两座岛连通。由于小Y想省力,所以他会把尽量少的海水变成路,不过小Y作为一个计算机的学生,他已经做到看山不是山看水不是水,他现在眼中的岛是二位数组里的1,他眼中的水是二维数组里的0,那么刚才的问题就变成了,给你一个只包含01的二维数组,且岛是一个由1组成的四联通的块,0则是水,现在要求你把最少的0变成1,使得二维数组里有且仅有的两座相连。

输入
第一行一个个整数N表示二维数组有N行N列
接下来N行,每行N个数字0或1,0代表水,1代表岛
1<=N<=100
输出
一个整数表示最少的需要把0变成1的数量
输入样例

3
010
000
001
输出样例
2

dfs超时
最小步数用BFS。从岛2试探性的往外侧一格一格的扩张,首先找出所有1步可达的点,然后找出所有2步可达的点,依次类推。
具体实现:可以使用一个队列来保存所有的岛2的点,每次取出队列头部元素tmp,查看点tmp四周的四个点。遇到未标记的点就加到队列中,并标记该点成本为tmp对应成本+1,直到遇到岛1的点。
-----来自赵二狗对我问题的解答

#include<bits/stdc++.h>
using namespace std;
char g[110][110];
int n,minn=0x3f3f3f3f;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct node{
	int x,y,t;
}p;
queue<node>q;
void pa(int x,int y)//将一块大陆用2标记 
{
 for(int i=0;i<4;i++)
 {
 	int tx=x+dir[i][0];
 	int ty=y+dir[i][1];
 	if(g[tx][ty]=='1')
 	{
 	 g[tx][ty]='2';
 	 p.x=tx;p.y=ty;p.t=0;
 	 q.push(p);
	 pa(tx,ty);	
	}
 }
}
void bfs(int sx,int sy)//寻找最短路 
{
 int x,y,t;
 while(!q.empty())
 {
 	p=q.front();q.pop();
 	x=p.x;y=p.y;t=p.t;
 	for(int i=0;i<4;i++)
 	{
 	 p.x=x+dir[i][0];
	 p.y=y+dir[i][1];
	 p.t=t+1;
	 if(p.x>=0&&p.x<n&&p.y>=0&&p.y<n&&g[p.x][p.y]!='2')
	 {
	  if(g[p.x][p.y]=='1')
	  {
	   cout<<t;return ;	
	  }	
	  g[p.x][p.y]='2';
	  q.push(p);
	 }	
	}
 }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=0;i<n;i++)
     cin>>g[i];
    for(int i=0;i<n;i++)
    {
     for(int j=0;j<n;j++)	
      if(g[i][j]=='1')
      {
      	g[i][j]='2';
      	p.x=i;p.y=j;p.t=0;
      	q.push(p);
     	pa(i,j);
     	bfs(i,j);
     	i=n; 
     	break;
	  }
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43540515/article/details/102672450
BFS