(dfs+simulation) 2018 Blue Bridge Cup C/C++ Group A Provincial Competition Zhenti 8 Global Warming

topic

Problem Description
  You have a NxN pixel photo of a certain sea area, "." means ocean, "#" means land, as follows:


  .##…
  .##…
  …##.
  …####.
  …###.
  …

Among them, a piece of land connected in the four directions of "up, down, left and right" forms an island. For example, there are 2 islands in the picture above.

Due to rising sea levels caused by global warming, scientists predict that a pixel of the edge of the island will be submerged by sea water in the next few decades. Specifically, if a land pixel is adjacent to an ocean (there are oceans in four adjacent pixels up, down, left, and right), it will be submerged.

For example, the sea area in the picture above will look like this in the future:


  …
  …
  …
  …#…
  …
  …

Please count: According to scientists' predictions, how many islands in the photo will be completely submerged.
Input format
  The first line contains an integer N. (1 <= N <= 1000)
  The following N rows and N columns represent a sea area photo.

The photo guarantees that the pixels in row 1, column 1, row N, and column N are all oceans.
Output format
  An integer representing the answer.
Sample Input
7

.##…
.##…
…##.
…####.
…###.

Sample Output
1

analyze

A # and all # connected to it form an island. The connection here refers to up, down, left and right. Then we can first calculate the number of islands before the change, then simulate the submerged islands, and then calculate the number of islands after the change. , and then subtraction is the answer. To calculate the number of islands, you need to use dfs to mark all the land of an island, and the change requires simulation + judgment.

code section

1. Loop through

Traverse the entire map, add one to the count if # appears, then dfs marks all # connected to it

	cin>>n;
	vector<vector<char> > _map(n,vector<char>(n));	//地图
	vector<vector<bool> > vis(n,vector<bool>(n,0)); 	//标记 
	
	
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cin>>_map[i][j];
	int oldcnt=0;
	
	for(int i=0;i<n;i++)	//计算变化前岛屿数量 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&vis[i][j]==0)
			{
    
    
				oldcnt++;
				dfs(i,j,_map,vis); 
			}
		}
	}
2.dfs

We must first understand what dfs does, mark all connected # from the current position, which are the four directions of up, down, left, and right, so for simplicity, we open two one-dimensional arrays as the direction coordinates to represent the change in direction, and then traverse the four directions. each direction, plus judge whether the next position can be walked or not, and each time mark the current position as already walked

const int dx[4]={
    
    0,0,1,-1};		//方向 
const int dy[4]={
    
    1,-1,0,0};

void dfs(int x,int y,vector<vector<char> > &_map,vector<vector<bool> > &vis)
{
    
    
	//出口
	vis[x][y]=1;
	//现在能做的事情
	for(int i=0;i<4;i++)
	{
    
    
		if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<n&&
		vis[x+dx[i]][y+dy[i]]==0&&
		(_map[x+dx[i]][y+dy[i]]=='#'||_map[x+dx[i]][y+dy[i]]=='!'))
		{
    
    
			dfs(x+dx[i],y+dy[i],_map,vis);
		}
	}
}
3. Simulate and judge the entire map

Before, I simulated and judged that if the current location would be submerged, I changed it to ., but later I found that this was not possible. In the end, all the grids in the map would be changed to ., and then I changed the grid to be submerged to !

bool check(int x,int y,vector<vector<char> > &_map)	//判断该岛屿是否会被淹没 
{
    
    
	for(int i=0;i<4;i++)
	{
    
    
		if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<n)
		{
    
    
			if(_map[x+dx[i]][y+dy[i]]=='.')
				return true;
		}
	}
	return false;	
}

	for(int i=0;i<n;i++)		//改变地图标记被淹没的陆地 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&check(i,j,_map))
			{
    
    
				_map[i][j]='!';
			} 
		}
	}	
4. Determine the number of islands after the change

If we directly calculate the number of islands as before, it will not work, because after some islands change, if they are directly calculated, they will become two islands. The meaning given in the question here is not very clear, so we start from # when judging, but! places are also marked and judged, as these lands were previously an island

	vector<vector<bool> > vis2(n,vector<bool>(n,0)); 	//标记 
	int nowcnt=0;
	
	for(int i=0;i<n;i++)	//计算变化后岛屿数量 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&vis2[i][j]==0)
			{
    
    
				nowcnt++;
				dfs(i,j,_map,vis2); 
			}
		}
	}

full code

#include <bits/stdc++.h>
using namespace std;

int n;
const int dx[4]={
    
    0,0,1,-1};		//方向 
const int dy[4]={
    
    1,-1,0,0};

void dfs(int x,int y,vector<vector<char> > &_map,vector<vector<bool> > &vis)
{
    
    
	//出口
	vis[x][y]=1;
	//现在能做的事情
	for(int i=0;i<4;i++)
	{
    
    
		if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<n&&
		vis[x+dx[i]][y+dy[i]]==0&&
		(_map[x+dx[i]][y+dy[i]]=='#'||_map[x+dx[i]][y+dy[i]]=='!'))
		{
    
    
			dfs(x+dx[i],y+dy[i],_map,vis);
		}
	}
}

bool check(int x,int y,vector<vector<char> > &_map)	//判断该岛屿是否会被淹没 
{
    
    
	for(int i=0;i<4;i++)
	{
    
    
		if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<n)
		{
    
    
			if(_map[x+dx[i]][y+dy[i]]=='.')
				return true;
		}
	}
	return false;	
}

int main (void)
{
    
    
	cin>>n;
	vector<vector<char> > _map(n,vector<char>(n));	//地图
	vector<vector<bool> > vis(n,vector<bool>(n,0)); 	//标记 
	
	
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cin>>_map[i][j];
	int oldcnt=0;
	
	for(int i=0;i<n;i++)	//计算变化前岛屿数量 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&vis[i][j]==0)
			{
    
    
				oldcnt++;
				dfs(i,j,_map,vis); 
			}
		}
	}
	
	
	for(int i=0;i<n;i++)		//改变地图标记被淹没的陆地 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&check(i,j,_map))
			{
    
    
				_map[i][j]='!';
			} 
		}
	}		

/*	
	for(int i=0;i<n;i++)		//输出改变后的地图 
	{
		for(int j=0;j<n;j++)
		{
			cout<<_map[i][j];
		}
		cout<<endl;
	}
*/	
	
	vector<vector<bool> > vis2(n,vector<bool>(n,0)); 	//标记 
	int nowcnt=0;
	
	for(int i=0;i<n;i++)	//计算变化后岛屿数量 
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			if(_map[i][j]=='#'&&vis2[i][j]==0)
			{
    
    
				nowcnt++;
				dfs(i,j,_map,vis2); 
			}
		}
	}
	cout<<oldcnt-nowcnt;
	
	return 0;
}

Summarize

Although there is a lot of code in this question, there are many places that are repeated, and the idea is not difficult. It is just the basic dfs, but there are some details that need to be paid attention to.

Guess you like

Origin blog.csdn.net/weixin_46035615/article/details/123967649