读入大量字符:快读配置
将cin,cout和scanf和printf解除绑定,提高效率。之后只能用cin,cout
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
在输入是很多字符时,需要吃掉换行符
cin>>N;
char next;
cin.get(next);
while(next!='\n')
cin.get(next);
例如在读入一个N*N的地图时:
//读入地图
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cin.get(ch[i][j]);
}
//读完一行需要将行尾的换行符吃掉
cin.get(next);
while(next!='\n')
cin.get(next);
}
宽搜:队列和自定义结构体
结构体:
struct point //存储一个格子的横纵坐标
{
int x,y;
};
宽搜模板:
void bfs(int i,int j)
{
mark[i][j]=1;//标记为已经访问
queue<point> q;//queue一般用自定义的类型
q.push({
i,j});//将当前格子封装到point里面并且插入队列
int jing=0,lingshuijing=0;//记录当前所给地图中的#以及和.相邻的#
while(!q.empty()) //一个while走完就是一个连通块走完了
{
point first=q.front();
q.pop();
jing++;
bool beiyan=0;
for(int k=0; k<4; k++)
{
int x=first.x+dx[k];
int y=first.y+dy[k];
if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='.')
{
beiyan=true;
}
//周边的#如果未被访问,则加入队列中
if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='#'&&mark[x][y]==0)
{
q.push({
x,y});
mark[x][y]=1;
}
}
if(beiyan)
{
lingshuijing++;
}
}
if(jing==lingshuijing)
{
res++;
}
}
例题:蓝桥杯2018全球变暖
- 完整题目:
你有一张某海域 N×NN×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
…
.##…
.##…
…##.
…####.
…###.
…
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 22 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
…
…
…
…
…#…
…
…
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数N。
以下 NN 行 NN 列,包含一个由字符”#”和”.”构成的 N×NN×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 11 行、第 11 列、第 NN 行、第 NN 列的像素都是海洋。
输出格式
一个整数表示答案。
数据范围
1≤N≤10001≤N≤1000
输入样例1:
7
…
.##…
.##…
…##.
…####.
…###.
…
输出样例1:
1
2. 思路:
首先需要找到地图中岛屿在哪——使用bfs进行搜索,连通块问题。
然后对找到的岛屿的每一块陆地判断他周围是否有海,只要四周有一块海,那么这块陆地就是要被淹没的陆地。
被淹没的岛就是其中的每一块陆地都和海相邻,所以对第二步中和海相邻的陆地进行计数,如果等于连通块中的一块的全部陆地,那么这个岛屿会被淹没。
4. 代码:
#include<bits/stdc++.h>
using namespace std;
char ch[100][100];
char mark[1000][1000]= {
0};
int N,res;
int dx[]= {
0,0,1,-1};
int dy[]= {
1,-1,0,0};
struct point //存储一个格子的横纵坐标
{
int x,y;
};
void bfs(int i,int j)
{
mark[i][j]=1;//标记为已经访问
queue<point> q;//queue一般用自定义的类型
q.push({
i,j});//将当前格子封装到point里面并且插入队列
int jing=0,lingshuijing=0;//记录当前所给地图中的#以及和.相邻的#
while(!q.empty()) //一个while走完就是一个连通块走完了
{
point first=q.front();
q.pop();
jing++;
bool beiyan=0;
for(int k=0; k<4; k++)
{
int x=first.x+dx[k];
int y=first.y+dy[k];
if(x>=0&&x<N&&y>=0&&y<N&&ch[x][y]=='.')
{
beiyan=true;
}
//周边的#如果未被访问,则加入队列中
if(x>=0&&x<N&&y>=0&&a