C++ 算法篇 广度(宽度)优先搜索(BFS)习题答案

宽度优先搜索是一种“盲目”搜索,所有结点的拓展都遵循“先进先出”的原则,所以采用“队列”来存储这些状态。宽度优先搜索的算法框架如下:

1、瓷砖

(queue写法)

#include<bits/stdc++.h>
using namespace std;
int px[4]={0,0,1,-1};
int py[4]={1,-1,0,0};
int main()
{  int h,w,a[60][60],i,j,ans=1,x,y;
   char c;   
   queue <int> dx,dy;
   cin>>h>>w;      
   for(i=1;i<=w;i++)
      for(j=1;j<=h;j++)
      {  cin>>c;
         if(c=='.')  a[i][j]=1;
         if(c=='#')  a[i][j]=0;
         if(c=='@') 
		 {  dx.push(i); dy.push(j);
		    a[i][j]=0;
		 }         
      } 
    while(!dx.empty())
    {  for(i=0;i<4;i++)
	   {  x= dx.front()+px[i];
	      y= dy.front()+py[i];
	      if(a[x][y]==1)
	      {  ++ans;
	         dx.push(x); dy.push(y);
	         a[x][y]=0;	     	
		  }
       }
	    dx.pop(); dy.pop();
	}
	cout<<ans<<endl;
	return 0;
}

(数组写法)

#include<bits/stdc++.h>
using namespace std;
int px[4]={0,0,1,-1};
int py[4]={1,-1,0,0};
int dx[200],dy[200];
int main()
{  int h,w,a[60][60],i,j,ans=1,x,y,head=0,tail=1;
   char c;     
   cin>>h>>w;      
   for(i=1;i<=w;i++)
      for(j=1;j<=h;j++)
      {  cin>>c;
         if(c=='.')  a[i][j]=1;
         if(c=='#')  a[i][j]=0;
         if(c=='@') 
		 {  dx[1]=i; dy[1]=j;
		    a[i][j]=0;
		 }         
      } 
    while(head<=tail)
    {  head++;
	   for(i=0;i<4;i++)
	   {  x= dx[head]+px[i];
	      y= dy[head]+py[i];
	      if(a[x][y]==1)
	      {  tail++;
		     ++ans;
	         dx[tail]=x; dy[tail]=y;
	         a[x][y]=0;		
		  }
       }
	}
	cout<<ans<<endl;
	return 0;
}

2、填涂颜色

#include<bits/stdc++.h>
using namespace std;
queue<int> dx,dy;
int py[2][4]={{-1,1,0,0},
              {0,0,-1,1}};
int a[32][32]={};
int main()
{   int n,i,j,x=1,y=1;
    cin>>n;
    for(i=1;i<=n;i++)
       for(j=1;j<=n;j++)   cin>>a[i][j];
    dx.push(x);
    dy.push(y);	
	 
    while(!dy.empty())
    {   for(i=0;i<4;i++) 
        {  x=dx.front()+py[0][i];  y=dy.front()+py[1][i];
		  // cout<<x<<" "<<y<<endl;        
		   if(a[x][y]==0&&x>=0&&y>=0&&x<=n+1&&y<=n+1) {  dx.push(x);dy.push(y);   a[x][y]=2; }
		}	    
		dx.pop();dy.pop();    	
	}
    for(i=1;i<=n;i++)
    {   for(j=1;j<=n;j++)  cout<<2-a[i][j]<<" ";
        cout<<endl;
	}     
}

3、求细胞数量

STL queue写法

#include<bits/stdc++.h>
using namespace std;
queue<int> dx,dy;
int py[2][4]={{-1,1,0,0},
              {0,0,-1,1}};
int a[105][105]={},ans=0;
int n,m,i,j,x,y;
char c;
void bfs(int x,int y)
{  int X,Y;   
   ans++;
   dx.push(x); dy.push(y);
   a[x][y]=0;
   while(!dy.empty())
    {   for(int i=0;i<4;i++) 
        {  X=dx.front()+py[0][i];  Y=dy.front()+py[1][i];		      
		   if(a[X][Y]) { dx.push(X);dy.push(Y);  a[X][Y]=0;}
		}	    
		dx.pop();dy.pop();    	
	}
}
int main()
{   cin>>n>>m;
    for(i=1;i<=n;i++)
       for(j=1;j<=m;j++)  { cin>>c; a[i][j]=(c!='0');   } 
	    
    for(i=1;i<=n;i++)
    {   for(j=1;j<=m;j++)      
          if(a[i][j])  bfs(i,j);  	  	  
	}   
	cout<<ans;  
}

数组写法

#include<bits/stdc++.h>
using namespace std;
int py[2][4]={{-1,1,0,0},
              {0,0,-1,1}};
int a[105][105]={},ans=0;
int n,m,i,j,x,y;
int dx[100],dy[100];
char c;
void bfs(int x,int y)
{  int X,Y,head=0,tail=1;
   ans++;
   dx[1]=x; dy[1]=y;
   a[x][y]=0;
   while(head<=tail)
    {   head++;
	    for(int i=0;i<4;i++) 
        {  X=dx[head]+py[0][i];  Y=dy[head]+py[1][i];		      
		   if(a[X][Y]) { tail++; dx[tail]=X;dy[tail]=Y;  a[X][Y]=0;}
		}		  	
	}
}
int main()
{   cin>>n>>m;
    for(i=1;i<=n;i++)
       for(j=1;j<=m;j++)  { cin>>c; a[i][j]=(c!='0');   } 
	    
    for(i=1;i<=n;i++)
    {   for(j=1;j<=m;j++)      
          if(a[i][j])  bfs(i,j);  	  	  
	}   
	cout<<ans;  
}

4、面积(area)

5、关系网络

#include<bits/stdc++.h>
using namespace std;
int i,j,n,x,y,a[101][101],t=0;
queue <int> q;
queue <int > step;
int main()
{   cin>>n>>x>>y;
    for(i=1;i<=n;i++)
	   for(j=1;j<=n;j++)
	     cin>>a[i][j];    
	int b[101]={0};
	q.push(x);
	b[x]=1;	
	step.push(0);
	while(!q.empty())
	{  for(i=1;i<=n;i++)
	   { if(a[q.front()][i]==1&& b[i]==0)
	     {   q.push(i);	          
	         step.push(step.front()+1);
	         if(i==y) {	cout<<step.front();	return 0; }	
			 b[i]=1;          
	     }
		   
	   }
	   q.pop();	
	   step.pop();
	}
}

用数组写

#include<bits/stdc++.h>
using namespace std;
int i,j,a[101][101];
int b[101],f[101],k[101];
int n,x,y,head=1,tail=1,tx;
int main()
{   cin>>n>>x>>y;
    for(i=1;i<=n;i++)
	   for(j=1;j<=n;j++)   cin>>a[i][j]; 
	b[x]=1;	f[1]=x; k[1]=0;
	while(head<=tail)
	{ tx=f[head];
	  if(tx==y) { cout<<k[head]-1; break;}	    
	  for(i=1;i<=n;i++)
	   { if(a[tx][i]==1&& b[i]==0)
	     {   tail++;         
	         f[tail]=i;
	         b[i]=1;  
			 k[tail]=k[head]+1;        
	     }
	   }
	   head++;
	}
}

6、最少经过城市

用 queue 写

#include<bits/stdc++.h>
using namespace std;
int i,j,n,a[101][101],d[101]={0},f[101]={};
queue <int> q;
int out(int x){
	if(x==0) return 0;
	cout<<char(x+64);
	if(f[x]!=0)  cout<<"--";
	return out(f[x]);
} 
int main()
{   cin>>n;
    for(i=1;i<=n;i++)
	   for(j=1;j<=n;j++)  cin>>a[i][j];    
	q.push(1);
	d[1]=1;
	while(!q.empty())
	{  for(i=1;i<=n;i++)
	     if(a[q.front()][i]==0&&d[i]==0 )
	     {  q.push(i);
	        d[i]=1;
	        if(f[i]==0)f[i]=q.front();
			if(i==n) out(n)	; 			    	
		 }		
		q.pop();
		//for(i=1;i<=n;i++) cout<<f[i]<<" ";
		//cout<<endl;   
	}
}

用数组写

#include<bits/stdc++.h>
using namespace std;
int i,j,n,a[101][101],d[101]={0},f[101]={};
int out(int x){
	if(x==0) return 0;
	cout<<char(x+64);
	if(f[x]!=0)  cout<<"--";
	return out(f[x]);
} 
int q[1001],tx;
int main()
{   cin>>n;
    for(i=1;i<=n;i++)
	   for(j=1;j<=n;j++)  cin>>a[i][j];    
	d[1]=1;
	int head=1,tail=1;
	q[1]=1;
	while(head<=tail)
	{   tx=q[head];
	    for(i=1;i<=n;i++)
	     if(a[tx][i]==0&&d[i]==0 )
	     {  tail++;
	        q[tail]=i;
	        d[i]=1;
	        if(f[i]==0)f[i]=q[head];
			if(i==n) out(n)	; 			    	
		 }		
		head++;
		//for(i=1;i<=n;i++) cout<<f[i]<<" ";
		//cout<<endl;   
	}
}

7、营救

#include<bits/stdc++.h>
using namespace std;
struct hhh
{	int h,l,s;//行,列,步数 
}qwq[1000005];
int jz[1005][1005]={0},d[1005][1005]={0};
int	main()
{	int bh[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	int head,tail,ax,ay,bx,by,flag=0,n,nx,ny;
	char ch;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{   getchar();getchar();
		for(int j=1;j<=n;j++)  jz[i][j]=getchar()-'0';  
	}
	scanf("%d %d %d %d",&ax,&ay,&bx,&by);	
	head=1;tail=1;//队列初始化 
	qwq[tail].h=ax;
	qwq[tail].l=ay;
	qwq[tail].s=0;
	tail++;
	d[ax][ay]=1;
	while(head<tail)
	{	for(int i=0;i<4;i++)
		{	nx=qwq[head].h+bh[i][0];
			ny=qwq[head].l+bh[i][1];
			if(nx<1||nx>n||ny<1||ny>n)	continue;
			if(jz[nx][ny]==0&& d[nx][ny]==0)
			{   d[nx][ny]=1;				
				qwq[tail].h=nx;//入队 
				qwq[tail].l=ny;
				qwq[tail].s=qwq[head].s+1;
				tail++;				
			}
			if(nx==bx&&ny==by)	flag=1;break;
		}
		if(flag==1)	break;
		head++;//不管有没有新成员入队都要对已有的成员出队操作 
	}//tail指向队尾(最后一个元素的下一个位置,所以-1) 	
	cout<<qwq[tail-1].s<<endl;	return 0;
}

8、最少转弯问题(TURN)

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值