全球变暖
你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7
…
.##…
.##…
…##.
…####.
…###.
…
【输出样例】
1
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
题目来源
第九届蓝桥杯省赛B组
题解
首先是定义所需变量:
char matrix[1005][1005];
int flag[1005][1005];
int N;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
其中N代表阶数,d[][]代表上下左右四个方向,matrix[][]表示陆地或海洋区域,flag[][]记录下其中位于陆地边缘的位置。
在判断哪些位置位于陆地边缘时,根据题意只需要判断它的上下左右四个位置,只要这四个位置存在有海洋,就说明这是一个陆地边缘位置。为什么要设置一个flag[][]作为标记,是因为如果找到了边缘位置,直接将它变为海洋,那么位于它内部的陆地也会受到影响被判定是边缘陆地。所以为了使其他不受位置影响,需要一个标记来记录下,最近只将标记过的位置置为海洋就行。
在标记过程中,我们只对陆地进行考虑,而且遍历时的下标都是从1开始的,因为题目要求输入不允许陆地出现在边界这种情况,所以也不需要考虑边界合法的问题。
void judge(){
for(int x=1;x<N;x++){
for(int y=1;y<N;y++){
if(matrix[x][y]=='#')
for(int i=0;i<4;i++){
int nx=x+d[i][0], ny=y+d[i][1];
if(matrix[nx][ny]=='.'){
flag[x][y]=1;
break;
}
}
}
}
}
标记完边缘陆地,就可以进行更新,将边缘陆地变为海洋了。
void renew(){
judge();
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(flag[i][j]==1){
matrix[i][j]='.';
}
}
}
}
更新完岛屿以后,最后一步就是找到一共有多少块陆地。这里可以从任意‘#’开始,不停地把邻接的部分用‘.’代替。一次dfs后与初始的‘#’邻接的所有‘#’就都被替换了,直至图中不再具有‘#’。总共进行的dfs次数就是答案了。
void dfs(int x, int y){
matrix[x][y]='*';
for(int i=0;i<4;i++){
int nx=x+d[i][0], ny=y+d[i][1];
if(matrix[nx][ny]=='#')
dfs(nx,ny);
}
}
int solve(){
int ans=0;
for(int i=1;i<N;i++){
for(int j=1;j<N;j++){
if(matrix[i][j]=='#'){
dfs(i,j);
ans++;
}
}
}
return ans;
}
全部示例如下:
#include<iostream>
using namespace std;
char matrix[1005][1005];
int flag[1005][1005];
int N;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
//标记出位于边缘的陆地
void judge(){
for(int x=1;x<N;x++){
for(int y=1;y<N;y++){
if(matrix[x][y]=='#')
for(int i=0;i<4;i++){
int nx=x+d[i][0], ny=y+d[i][1];
if(matrix[nx][ny]=='.'){
flag[x][y]=1;
break;
}
}
}
}
}
//更新岛屿
void renew(){
judge();
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(flag[i][j]==1){
matrix[i][j]='.';
}
}
}
}
//深搜一片陆地
void dfs(int x, int y){
matrix[x][y]='*';
for(int i=0;i<4;i++){
int nx=x+d[i][0], ny=y+d[i][1];
if(matrix[nx][ny]=='#')
dfs(nx,ny);
}
}
//找到几片陆地
int solve(){
int ans=0;
for(int i=1;i<N;i++){
for(int j=1;j<N;j++){
if(matrix[i][j]=='#'){
dfs(i,j);
ans++;
}
}
}
return ans;
}
int main(){
cin>>N;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cin>>matrix[i][j];
flag[i][j]=0;
}
}
renew();
cout<<solve();
return 0;
}