上周加深了对深搜的理解并做了些练习题,这周详细了解了广搜,知识点网上就有很多,在看关于广搜的博客时,我稍微对广搜有了一些理解,并做了一些关于广搜的题目,只有七道,两道不会,提高我暂时还不配。
在老师发的题单当中,我发现染色问题用广搜也可以去解决,于是
还是这一道题,用不同的方法再做一次
#include<bits/stdc++.h>
using namespace std;
int n,m;
int sum,a[1000],b[1000];
int x[]= {1,-1,0,0},y[]= {0,0,-1,1};
char ch;
bool boolr,s[1000][1000];
void asd(int u,int v)
{
int t,q,r=1,f=0;
a[r]=u;
b[r]=v;
s[u][v]=0;
while(r>f)
{
for(int i=0; i<4; i++)
{
t=a[f+1]+x[i];
q=b[f+1]+y[i];
if(t>0&&q>0&&t<=n&&q<=m&&s[t][q])
{
r++;
s[t][q]=0;
a[r]=t;
b[r]=q;
if(boolr)
{
sum++;
}
}
}
f++;
}
}
int main()
{
memset(s,1,sizeof(s));
cin>>n>>m;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>ch;
ch=='0'?s[i][j]=1:s[i][j]=0;
}
}
for(int i=0; i<=n+1; i++)
{
for(int j=0; j<=m+1; j++)
{
if(j==0||i==0||i==n+1||j==m+1)
{
if(s[i][j])
{
asd(i,j);
}
}
}
}
boolr=1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(s[i][j])
{
asd(i,j);
sum++;
}
}
}
cout<<sum;
return 0;
}
在这七道题目当中,这种类型问题有四道,这代码比广搜长了一点不止,但是通过这道题,我感觉到广搜就是一种辐射式的搜索,一层一层扩散所有相关点,以此寻找符合条件的,与深搜的搜索顺序有着很大不同。
而且通过这道题,明白了这类题广搜程序的大致模板
void asd(int u,int v)
{
int t,q,r=1,f=0;
a[r]=u;
b[r]=v;
s[u][v]=false;
while(r>f)
{
for(int i=0;i<4;i++)
{
t=a[f+1]+x[i];
q=b[f+1]+y[i];
if(t>0&&q>0&&t<=n&&q<=m&&s[t][q])
{
r++;
s[t][q]=false;
a[r]=t;
b[r]=q;
if(boolr)
{
sum++;
}
}
}
f++;
}
}
这道题对我的启发还是很大的。
接下来,广搜招牌题型,最短路径。
非常有意思的一道题目,但是我不会,单纯是最短路径问题我觉得没准我还有能力写出来,但是,题目中加的几个条件让我感觉他就不是最短路径问题。所以我自己在网上找了几道单纯的最短路径问题去做。
题目如下
定义一个二维数组:
int maze[5][5] = {undefined
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
这道题只需要在寻找最短路径的过程中将坐标保存即可。
#include<bits/stdc++.h>
using namespace std;
int zb[150][150];
int book[150][150];
int fx[4][2]= {0,1,1,0,0,-1,-1,0};
struct node
{
int x,y,step;
int a[150],b[150];
} qq[150];
int main()
{
int i,j;
node u,v,w;
queue<node>q;
memset(book,0,sizeof(book));
for(i=0; i<5; i++)
for(j=0; j<5; j++)
cin>>zb[i][j];
u.x=0;
u.y=0;
u.step=0;
u.a[0]=0;
u.b[0]=0;
book[u.x][u.y]=1;
q.push(u);
while(!q.empty())
{
v=q.front();
q.pop();
if(v.x==4&&v.y==4)
{
for(i=0; i<=v.step; i++)
cout<<"("<<v.a[i]<<", "<<v.b[i]<<")"<<endl;
break;
}
w=v;
for(i=0; i<4; i++)
{
w.x=v.x+fx[i][0];
w.y=v.y+fx[i][1];
if(w.x>=0&&w.x<5&&w.y>=0&&w.y<5&&book[w.x][w.y]==0&&zb[w.x][w.y]!=1)
{
book[w.x][w.y]=1;
w.step=v.step+1;
w.a[w.step]=w.x;
w.b[w.step]=w.y;
q.push(w);
}
}
}
return 0;
}
最短路径问题是广搜中的经典题型,难度一般,但是对于我还是需要码上几个小时。
最近学习状态良好,在学习广搜的过程中,顺便学习了关于图的一些知识,这对我对广搜的题有了更多的思考,对题目也有更多的想法,在做了一点点广搜题目后,我感觉能用深搜就不会去用广搜
广搜代码段好长,虽然不用递归可能会加快程序运行速度,但是对于码代码想思路都比较慢的我来说,可能还是深搜更适合我?