分析
初看这题有点蒙,不知道如何判断一个岛屿到底是内岛还是外岛,因为同样都是四周环海。陆地不好判断,可以反过来判断海洋。判断这个海到底是内海(不与边界相邻)还是外海(与边界相邻),如果这个岛屿与外海相邻,则这个岛屿为外岛,否则则是内岛。一下子思路清晰了。
第一步:标记海洋。给所有外海标记为‘w’,不过要注意标记海洋的dfs走法有八个方向
vector<string> grid(54);
int dir[8][2]={0,1,0,-1,-1,0,1,0,-1,-1,-1,1,1,-1,1,1};
void mark(int x,int y){
grid[x][y]='w';
for(int i=0;i<8;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m||grid[nextx][nexty]!='0')
continue;
mark(nextx,nexty);
}
}
//左边界和右边界
for(int i=0;i<n;i++){
if(grid[i][0]=='0')
mark(i,0);
if(grid[i][m-1]=='0')
mark(i,m-1);
}
//上边界和下边界
for(int i=0;i<m;i++){
if(grid[0][i]=='0')
mark(0,i);
if(grid[n-1][i]=='0')
mark(n-1,i);
}
第二步:标记陆地,如果为外岛则计数
bool flag;
void dfs(int x,int y){
grid[x][y]='a';
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m||grid[nextx][nexty]=='a'||grid[nextx][nexty]=='0')
continue;
if(grid[nextx][nexty]=='w'){
flag=true;
continue;
}
dfs(nextx,nexty);
}
}
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(grid[i][j]=='1'){
flag=false;
dfs(i,j);
if(flag){//如果该岛为外岛
cnt++;
}
}
}
}
cout<<cnt<<endl;
完整代码如下
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define endl '\n'
int n,m;
vector<string> grid(54);
int dir[8][2]={0,1,0,-1,-1,0,1,0,-1,-1,-1,1,1,-1,1,1};
bool flag;
void mark(int x,int y){
grid[x][y]='w';
for(int i=0;i<8;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m||grid[nextx][nexty]!='0')
continue;
mark(nextx,nexty);
}
}
void dfs(int x,int y){
grid[x][y]='a';
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m||grid[nextx][nexty]=='a'||grid[nextx][nexty]=='0')
continue;
if(grid[nextx][nexty]=='w'){
flag=true;
continue;
}
dfs(nextx,nexty);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
for(int k=0;k<t;k++){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>grid[i];
}
for(int i=0;i<n;i++){
if(grid[i][0]=='0')
mark(i,0);
if(grid[i][m-1]=='0')
mark(i,m-1);
}
for(int i=0;i<m;i++){
if(grid[0][i]=='0')
mark(0,i);
if(grid[n-1][i]=='0')
mark(n-1,i);
}
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(grid[i][j]=='1'){
flag=false;
dfs(i,j);
if(flag){
cnt++;
}
}
}
}
cout<<cnt<<endl;
}
return 0;
}
这道题还是非常有意思的,需要稍微转一下弯,既然岛屿不好判断,那么我们就判断海洋,然后给他们标记区分开来,然后判断岛屿是否与外海相邻,相邻则为外岛。