题目:宝岛探险(来自啊哈算法)
题目内容:
小哼通过秘密方法得到一张不完整的钓鱼岛航拍地图。钓鱼岛由一个主岛和一些附属岛屿组成,小哼决定去钓鱼岛探险。下面这个10*10的二维矩阵就是钓鱼岛的航拍地图。图中数字表示海拔,0表示海洋,1~9都表示陆地。小哼的飞机将会降落在(6,8)处,现需要计算出小哼降落所在岛的面积(即有多少格子)。注意此处我们把与小哼降落点上下左右相链接的陆地均视为同一岛屿。
本题可以使用深度优先搜索也可以使用广度优先搜索,首先我们先来看深度优先搜索的代码
#include <iostream>
using namespace std;
struct note{ //用结构体来定义队列的属性
int x;
int y;
};
int main()
{
struct note queue[2501]; //声明一个队列
int head,tail;
int a[51][51];
int book[51][51]={0};//标记数组标记已经访问过的点
int i,j,k,sum,max=0,mx,my,n,m,startx,starty,tx,ty;
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//定义
cin>>n>>m>>startx>>starty;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>a[i][j];
head=1;
tail=1;
queue[tail].x=startx; //为首队列赋值,因为此时的tail==head
queue[tail].y=starty;
tail++;
book[startx][starty]=1;
sum=1;
while(head<tail){ //广度优先搜索(BFS)不使用递归使用循环操作队列的方式,当head==tail时搜索完毕退出循环
for(k=0;k<=3;k++){
tx=queue[head].x+next[k][0]; //令tx等于下一个点的横坐标
ty=queue[head].y+next[k][1]; //令ty等于下一个点的纵坐标
if(tx<1||tx>n||ty<1||ty>m) //判断下一个点是否越界
continue;
if(a[tx][ty]>0&&book[tx][ty]==0){ //找到符合题意的点进行操作
sum++;
book[tx][ty]=1;
queue[tail].x=tx;
queue[tail].y=ty;
tail++;
}
}
head++; //一定记得要让head++,即让队列头元素出队这样
}
cout<<sum;
return 0;
}
运行结果如下图所示结果正确
广度优先搜索是借助队列和循环来完成
下面我们来看看这题用DFS(深度优先搜索)怎么去解决
这题用DFS解决也很方便代码如下
#include <iostream>
using namespace std;
int a[51][51];
int book[51][51],n,m,sum;
void dfs(int x,int y)
{
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//定义方向数组
int tx,ty;
for(int k=0;k<=3;k++){
tx=x+next[k][0]; //令tx为下一个要找的点
ty=y+next[k][1]; //令ty为下一个要找的点
if(tx<1||tx>n||ty<1||ty>m) //判断是否越界
continue;
if(a[tx][ty]>0&&book[tx][ty]==0){ //找到符合条件的点操作好后用递归的方法去下找一点
sum++;
book[tx][ty]=1;
dfs(tx,ty); //找下一个点
}
}
return ; //for循环进行完毕返回空
}
int main()
{
int startx,starty;
cin>>n>>m>>startx>>starty;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
book[startx][starty]=1;
sum=1;
dfs(startx,starty);
cout<<sum;
return 0;
}
运行结果和BFS运行结果一样
搜索在很多题目中都是很有用的方法,打好搜索基础,对于以后学习剪枝搜索解决问题很有帮助
不过并不是搜索题目都可以用搜索顺利解决,暴力搜索或者普通的剪枝搜索都涉及到时间的问题,很可能会超时
这时候动态规划就显得尤为重要
本题测试数据如下
10 10 6 81 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
输出结果为:38