倪文迪陪你学蓝桥杯2021寒假每日一题:1.20日(2018省赛A组第8题)
2021年寒假每日一题,2017~2019年的省赛真题。
本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供。
后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: https://blog.csdn.net/weixin_43914593/category_10721247.html
提供C++、Java、Python三种语言的代码。
文章目录
- 1、题目描述
- 2、题解
- 3、DFS的C++代码
- 4、BFS的Python代码
- 5、Java代码
2018省赛A组第8题“全球变暖” ,题目链接:
http://oj.ecustacm.cn/problem.php?id=1365
https://www.dotcpp.com/oj/problem2276.html
1、题目描述
你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入:第一行包含一个整数N。 (1 <= N <= 1000) 。以下N行N列代表一张海域照片。 照片保证第1行、第1列、第N行、第N列的像素都是海洋。
输出:一个整数表示答案。
2、题解
题目一看就是“连通块问题”,是基础搜索。用DFS或BFS都行:遍历一个连通块(找到这个连通块中所有的’#‘,并标记已经搜过,不用再搜);再遍历下一个连通块…;遍历完所有连通块,统计有多少个连通块。
回到题目,什么岛屿不会被完全淹没?若岛中有个陆地(称为高地),它周围都是陆地,那么这个岛不会被完全淹没。
用DFS或BFS搜出有多少个岛(连通块),并且在搜索时统计那些没有高地的岛(连通块)的数量,就是答案。
因为每个像素点只用搜一次且必须搜一次,所以复杂度是O(N2)O(N^2)O(N2)的,不可能更好了。
下面用C++代码实现DFS,用Python实现BFS,并附上Java代码。
3、DFS的C++代码
DFS所有的点,若遇到’#‘,就继续DFS这个’#‘周围的’#‘。把搜过的’#‘标记为已经搜过,不用再搜。标记那些没有高地的岛的数量,就是答案。
#include<bits/stdc++.h>
using namespace std;int n;
char a[1010][1010]; //地图
int vis[1010][1010]={0}; //标记是否搜过
int d[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}}; //四个方向
int flag; //用于标记这个岛中是否被完全淹没
void dfs(int x, int y){vis[x][y] = 1; //标记这个'#'被搜过。注意为什么可以放在这里if(a[x][y+1]=='#' && a[x][y-1]=='#' && a[x+1][y]=='#' && a[x-1][y]=='#')flag = 1; //上下左右都是陆地,不会淹没for(int i = 0; i < 4; i++){ //继续DFS周围的陆地int nx = x + d[i][0], ny = y + d[i][1];//if(nx>=1 && nx<=n && ny>=1 && ny<=n && vis[nx][ny]==0 && a[nx][ny]=='#') //题目说边上都是水,所以不用这么写了if(vis[nx][ny]==0 && a[nx][ny]=='#') //继续DFS未搜过的陆地,目的是标记它们dfs(nx,ny);}
}int main(){cin >> n;for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)cin >> a[i][j];int ans = 0 ;for(int i = 1; i <= n; i++) //DFS所有像素点for(int j = 1; j <= n; j++)if(a[i][j]=='#' && vis[i][j]==0){flag = 0;dfs(i,j);if(flag == 0) //这个岛全部被淹ans++; //统计岛的数量}cout<<ans<<endl;return 0;
}
4、BFS的Python代码
下面的代码实现了BFS。注意Python有两种队列实现方式:
(1)用queue实现队列操作,见下面的代码。
(2)Python的list就是一个普通队列,代码中的注释是用list实现的队列。
from queue import *def bfs(x,y):dirt=[(0,1),(0,-1),(1,0),(-1,0)] q = Queue() #q = [(x,y)] #也可以用list来实现队列q.put((x,y))vis[x][y]=1flag = 0 while not q.empty(): #while len(q)!=0: current=q.get() #current=q.pop(0)x,y=current[0],current[1]if flag == 0:if a[x][y+1]=='#' and a[x][y-1]=='#' and a[x+1][y]=='#' and a[x-1][y]=='#':flag = 1 #这个岛不淹没 for i in range(4):newx=x+dirt[i][0]newy=y+dirt[i][1]if vis[newx][newy]==0 and a[newx][newy]=="#": q.put((newx,newy)) #q.append((newx,newy))vis[newx][newy]=1 #注意为什么放在这里if flag == 0: #这个岛被淹return Truereturn False #这个岛不淹没
n=int(input())
a=[]
for i in range(n):a.append(list(input()))
vis=[]
for i in range(n):vis.append([0]*n)
ans=0
for i in range(n):for j in range(n):if vis[i][j]==0 and a[i][j]=="#": if bfs(i,j): #这个岛被淹ans+=1
print(ans)
5、Java代码
下面的Java代码实现了BFS。
//http://oj.ecustacm.cn/ User: 1840131230
import java.math.BigInteger;
import java.util.*;
public class Main
{static class node{int x,y;node(int x,int y){this.x=x;this.y=y;}}static int n,sums=0;static char map[][];static int vist[][];static int dx[]= {0,0,-1,1};static int dy[]= {-1,1,0,0};static void bfs(int x,int y) {Queue<node> que=new LinkedList<node>();que.add(new node(x,y));vist[x][y]=1;boolean flag=true;while(!que.isEmpty()) {node p=que.remove();int xx=p.x;int yy=p.y;int sum=0;for(int i=0;i<4;i++) {int xxx=xx+dx[i];int yyy=yy+dy[i];if(xxx>=0&&xxx<n&&yyy>=0&&yyy<n&&map[xxx][yyy]=='#') {sum++;}}if(sum==4)flag=false;for(int i=0;i<4;i++) {int xxx=xx+dx[i];int yyy=yy+dy[i];if(xxx>=0&&xxx<n&&yyy>=0&&yyy<n&&vist[xxx][yyy]==0&&map[xxx][yyy]=='#') {vist[xxx][yyy]=1;que.add(new node(xxx,yyy));sum++;}}}if(flag)sums++;}public static void main(String[] args) {Scanner sc=new Scanner(System.in);n=sc.nextInt();map=new char[n][n];vist=new int[n][n];for(int i=0;i<n;i++) {map[i]=sc.next().toCharArray();}for(int i=0;i<n;i++) {for(int j=0;j<n;j++) {if(map[i][j]=='#'&&vist[i][j]==0) {bfs(i,j);}}}System.out.println(sums);}
}
倪文迪陪你学蓝桥杯2021寒假每日一题:1.20日(2018省赛A组第8题)相关推荐
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.19日(2018省赛A组第7题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: htt ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.15日(2018省赛A组第3题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: htt ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.21日(2018省赛A组第9题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家每天看博客蓝桥杯专栏: htt ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:2.1日(2019省赛A组第10题)
2021年寒假每日一题,2017~2019年的省赛真题.本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供.每日一题,关注蓝桥杯专栏: https://blog.csdn.net/w ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.26日(2019省赛A组第4题)
2021年寒假每日一题,2017~2019年的省赛真题.本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供.每日一题,关注蓝桥杯专栏: https://blog.csdn.net/w ...
- 倪文迪陪你学蓝桥杯2021寒假每日一题:1.11日(2017省赛A第9题)
2021年寒假每日一题,2017~2019年的省赛真题. 本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供. 后面的每日一题,每题发一个新博文,请大家看博客目录:https://b ...
- 第十二届 2021年1月 蓝桥杯青少年组省赛C++组 第1题--第3题(scratch实现)
第十二届2021年蓝桥杯青少年组省赛 第十二届2021年蓝桥杯青少年组省赛_lybc2019的博客-CSDN博客 第十二届蓝桥杯青少年组省赛C++中级组试卷讲解(2021.01) 第十二届蓝桥杯青少年 ...
- 第十二届蓝桥杯 2021年国赛真题 (Java 大学A组)
蓝桥杯 2021年国赛真题(Java 大学 A 组 ) #A 纯质数 按序枚举 按位枚举 #B 完全日期 朴素解法 朴素改进 #C 最小权值 动态规划 #D 覆盖 变种八皇后 状压 DP #E 123 ...
- 第十二届蓝桥杯 2021年省赛真题 (Java 大学B组) 第一场
蓝桥杯 2021年省赛真题 (Java 大学B组 ) #A ASC #B 卡片 朴素解法 弯道超车 #C 直线 直线方程集合 分式消除误差 平面几何 #D 货物摆放 暴力搜索 缩放质因子 #E 路径 ...
最新文章
- 拖拽公式图片、一键转换LaTex公式,开源公式识别神器
- java ssssss_Java 时间字符串(HH:mm:ss.SSS) 转换成毫秒(milliseconds)
- Python列表中字符串转数字的方法
- 去掉一键还原 开机按k键
- boost::fusion::insert用法的测试程序
- http --- 基本认证与摘要认证
- 正则表达式的贪婪模式、非贪婪模式、占有模式
- 分布式资本沈波:未来区块链杀手级应用将出现在“+区块链”
- Linux 监控命令 iostat
- oracle+mybatis查询遇到CHAR类型字段
- 重读GhostNet:使用轻量操作代替部分传统卷积层生成冗余特征以减少计算量
- python在医学领域应用_深度学习在健康医疗领域应用
- C#生成Guid,SqlServer生成Guid
- 关于KL距离(KL Divergence)
- android 古诗,古诗词朗诵安卓
- 用 Python 做股市数据分析(2)
- Hbase性能测试及优化过程记
- linux下回收站无法清空 解决
- 利用AnyLogic软件搭建多智能体模型验证Lanchester方程线性律和平方律
- 大学计算机基础知识判断题,大学计算机基础知识考试试题及答案