标题:全球变暖
你有一张某海域NxN像素的照片,“。”表示海洋,“#”表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中“上下左右”四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N.(1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行,第1列,第N行,第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7
.......
.##....
.##....
....##.
..####.
...###.
.......
【输出样例】
1
资源约定:
峰值内存消耗(含虚拟机)<256M
CPU消耗<1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...”的多余内容。
注意:
主函数需要返回0;
只使用ANSI C / ANSI C ++标准;
。调用不要依赖于编译环境或操作系统的特殊函数
所有依赖的函数必须明确地在源文件中的#include <XXX>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
思路深搜并且标记统计原来的岛屿数目以及被淹没后
#include<iostream> #include<stdlib.h> #include<string.h> #include<stdio.h> using namespace std; bool flag;//标记是否岛屿沉没 char a[1010][1010];//地图保存 int cnt=0;//统计周围#的数目 int n;// int d[4][2]= {1,0,-1,0,0,1,0,-1};//枚举方向的数组 int ans=0;//被淹没后的岛屿个数 int res_ans=0;//没被淹没的岛屿的个数 void dfs(int x,int y)//回溯 { if(a[x][y]!='#')//如果这个点被标记成已经探索的岛屿内容或者是海洋,那么就返回 return ; if(x>=n||x<0||y>=n||y<0)//如果越界了也是返回 return ; if(flag==false)//如果还没确定不会被淹没,即当前是被淹没状态 {cnt=0;//统计这个岛屿的当前点坐标x,y的上下左右的四个点是不是都是'#',如果确实是这样的,那么为我们就可以确定这个岛屿不会被淹没,我们姑且叫这样的点叫做不可淹没点,,那么只要一个岛屿有一个这样的点就一定不会被淹没 for(int i=0; i<4; i++)//枚举四个方向 { int tx=x+d[i][0]; int ty=y+d[i][1]; if(tx<n&&tx>=0&&ty<n&&ty>=0&&a[tx][ty]!='.')//假设枚举的四周的点不会超界并且不是海洋,那么cnt数目+1 { cnt++; } } if(cnt==4)//如果四周的点都是这样的那么这个点就是不可淹没点 { ans++;//最后不会被淹没的点+! flag=true;//这个岛屿标记已经确定,当前岛屿是不可以被淹没的,所以当回溯这个岛屿其他点的时候就不用再来检查了,因为一个岛屿有一个这样的不可淹没点就够了 } } a[x][y]='*';//对于已经探索的岛屿的内容标记成'*', for(int i=0; i<4; i++) { int tx=x+d[i][0]; int ty=y+d[i][1]; dfs(tx,ty);//对于四个方向进行回溯岛屿的所有点 } } int main() { cin>>n; for(int i=0; i<n; i++) { scanf("%s",a[i]); }//输入数据 for(int i=0; i<n; i++) { for(int j=0; j<n; j++) {//遍历地图的所以坐标 if(a[i][j]=='#')//如果被找到的是同一个岛屿那么会被标记成'*',不会进入回溯,只有是'#'才说明是未被搜索的岛屿的一角 { res_ans++;//那么岛屿数目加1 flag=false;//假设会淹没 dfs(i,j);//回溯标记这个岛屿的所有点的坐标,并且如果不会被完全的淹没,那么就标记 } } } cout<<res_ans-ans<<endl;//输出答案 }