12035. 宝岛探险
普及/提高-
题目详情
小哼通过秘密方法得到一张不完整的钓鱼岛航拍地图。钓鱼岛由一个主岛和一些附属岛屿组成,小哼决定去钓鱼岛探险。下面这个10*10的二维矩阵就是钓鱼岛的航拍地图。图中数字表示海拔,0表示海洋,1~9都表示陆地。小哼的飞机将会降落在(6,8)处,现在需要计算出小哼降落所在岛的面积(即有多少个格子)。注意此处我们把与小哼降落点上下左右相链接的陆地均视为同一岛屿。
输入格式:
一行4个整数,前两个整数表示n行m列,后两个整数表示降落的坐标x行y列 接下来n行,每行m列,整数之间用空格隔开表示地图。
输出格式:
一个整数表示岛屿的面积
限制:
n<=100 m<=100
样例 1 :
输入: 10 10 6 8 1 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
1)dfs 解决
/**
1)dfs 解决
*/
/**
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn =110;
int maze[maxn][maxn];
bool hs[maxn][maxn];
int n,m;
int sum=0;
void dfs(int x,int y)
{
++sum;
hs[x][y]=1;
int X[]={1,0,-1,0};
int Y[]={0,1,0,-1};
for(int i=0;i<4;++i)
{
int newx=x+X[i];
int newy=y+Y[i];
if(newx>=1 && newx<=n && newy>=1 && newy<=m && maze[newx][newy]>0 && hs[newx][newy]==0)
dfs(newx,newy);
}
}
int main()
{
cin >> n >>m;
int x,y;
cin >> x >> y;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin >> maze[i][j];
dfs(x,y);
cout << sum << endl;
return 0;
}
*/
2) bfs 解决:
/**
2) bfs 解决:
*/
/**
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int,int> PII;
const int maxn =110;
int maze[maxn][maxn];
bool hs[maxn][maxn];
int n,m;
int sum=0;
void bfs(int x,int y)
{
queue<PII> q;
q.push({x,y});
hs[x][y]=1;
int X[]={1,0,-1,0};
int Y[]={0,1,0,-1};
while(q.size())
{
PII top = q.front();
q.pop();
++sum;
x=top.first,y=top.second;
for(int i=0;i<4;++i)
{
int newx=x+X[i];
int newy=y+Y[i];
if(newx>=1 && newx<=n && newy>=1 && newy<=m && maze[newx][newy]>0 && hs[newx][newy]==0)
{
q.push({newx,newy});
hs[newx][newy]=1;
}
}
}
}
int main()
{
cin >> n >>m;
int x,y;
cin >> x >> y;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin >> maze[i][j];
bfs(x,y);
cout << sum << endl;
return 0;
}
*/
3) 着色法:以某个点为源点对其临近的点进行着色。
例如,我们可以将小哼降落的岛都改为-1,表示该岛已经被小哼玩遍了。
我们这里用bfs来着色,同理,dfs一样;
/**
3) 着色法:以某个点为源点对其临近的点进行着色。
例如,我们可以将小哼降落的岛都改为-1,表示该岛已经被小哼玩遍了。
我们这里用bfs来着色,同理,dfs一样;
*/
/**
#include <iostream>
#include <algorithm>
#include <queue>
#include <iomanip>
using namespace std;
typedef pair<int,int> PII;
const int maxn =110;
int maze[maxn][maxn];
bool hs[maxn][maxn];
int n,m;
int sum=0;
void bfs(int x,int y,int color)
{
queue<PII> q;
q.push({x,y});
hs[x][y]=1;
int X[]={1,0,-1,0};
int Y[]={0,1,0,-1};
while(q.size())
{
PII top = q.front();
q.pop();
++sum;
x=top.first,y=top.second;
maze[x][y]= color; //着色
for(int i=0;i<4;++i)
{
int newx=x+X[i];
int newy=y+Y[i];
if(newx>=1 && newx<=n && newy>=1 && newy<=m && maze[newx][newy]>0 && hs[newx][newy]==0)
{
q.push({newx,newy});
hs[newx][newy]=1;
}
}
}
}
int main()
{
cin >> n >>m;
int x,y;
cin >> x >> y;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin >> maze[i][j];
bfs(x,y,-1);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
cout << setw(5) << maze[i][j] ;
puts("");
}
cout << sum << endl;
return 0;
}
*/
/**
4)假如我们想知道地图上有多少个独立的小岛怎么处理;
简单,对每个独立的小岛进行着色,也就是图的遍历问题;
求一个图中独立子图的问题,据说叫做 Floodfill漫水填充法,也称为种子填充法;
*/
/**
4)假如我们想知道地图上有多少个独立的小岛怎么处理;
简单,对每个独立的小岛进行着色,也就是图的遍历问题;
求一个图中独立子图的问题,据说叫做 Floodfill漫水填充法,也称为种子填充法;
*/
#include <iostream>
#include <algorithm>
#include <queue>
#include <iomanip>
using namespace std;
typedef pair<int,int> PII;
const int maxn =110;
int maze[maxn][maxn];
int n,m;
int sum=0;
void bfs(int x,int y,int color)
{
queue<PII> q;
q.push({x,y});
int X[]={1,0,-1,0};
int Y[]={0,1,0,-1};
while(q.size())
{
PII top = q.front();
q.pop();
++sum;
x=top.first,y=top.second;
maze[x][y]= color; //着色
for(int i=0;i<4;++i)
{
int newx=x+X[i];
int newy=y+Y[i];
if(newx>=1 && newx<=n && newy>=1 && newy<=m && maze[newx][newy]>0)
{
q.push({newx,newy});
}
}
}
}
int main()
{
cin >> n >>m;
int x,y;
cin >> x >> y;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin >> maze[i][j];
int num=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(maze[i][j]>0)
{
--num;
bfs(i,j,num);
}
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
cout << setw(5) << maze[i][j] ;
puts("");
}
printf("有 %d 个独立的小岛\n",-num);
return 0;
}