CodeForce 377A dfs Maze

Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, or is a wall. You can go from one cell to another only if both cells are empty and have a common side.
Pavel drew a grid maze with all empty cells forming a connected area. That is, you can go from any empty cell to any other one. Pavel doesn’t like it when his maze has too little walls. He wants to turn exactly k empty cells into walls so that all the remaining cells still formed a connected area. Help him.

Input
The first line contains three integers n, m, k (1 ≤ n, m ≤ 500, 0 ≤ k < s), where n and m are the maze’s height and width, correspondingly, k is the number of walls Pavel wants to add and letter s represents the number of empty cells in the original maze.
Each of the next n lines contains m characters. They describe the original maze. If a character on a line equals “.”, then the corresponding cell is empty and if the character equals “#”, then the cell is a wall.

Output
Print n lines containing m characters each: the new maze that fits Pavel’s requirements. Mark the empty cells that you transformed into walls as “X”, the other cells must be left without changes (that is, “.” and “#”).
It is guaranteed that a solution exists. If there are multiple solutions you can output any of them.

Examples

Input
3 4 2
#…#
…#.
#…
Output
#.X#
X.#.
#…

题意就是给你个迷宫,让你将其中的点改成X后仍然联通,让后输出改变后的迷宫。

这个题比较明显是要用dfs,既然是改变后仍然联通,那我们知道dfs实际上是一个搜索树,搜“.”的时候树本身就是联通的,只需要将树的最后改成X可以保证前面的都联通,也就是dfs回溯的时候将k个点改成X即可.

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int N=510;

int n,m,k,x,y;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
char str[N][N];
bool st[N][N];

void dfs(int x,int y)
{
	if(!k) return;//改变完后及时return,不然超时
	int xx,yy;
	for(int i=0;i<4;i++)
	{
		xx=x+dir[i][0];
		yy=y+dir[i][1];
		if(str[xx][yy]=='X'||xx<1||xx>n||yy<1||yy>m||st[xx][yy]||str[xx][yy]=='#')
			continue;
		st[xx][yy]=true;
		
		dfs(xx,yy);
		if(k) str[xx][yy]='X',k--;
		
		st[xx][yy]=false;
	}
	
}

int main()
{
	cin>>n>>m>>k;
	
	for(int i=1;i<=n;i++)
		scanf("%s",str[i]+1);
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		if(str[i][j]=='.')
		{
			dfs(i,j);
			break;
		}
	
	for(int i=1;i<=n;i++)
		cout<<str[i]+1<<endl;
	
	return 0;
}

下面这份代码是将走过的g-k个路径标记,输出的时候没走过的路径输出X即可,因为既然走过了,那么肯定是联通的。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

const int N=600;

int n,m,k,g,res;
char str[N][N];
bool vis[N][N],bj;
int dir[4][2]={1,0,-1,0,0,1,0,-1};

void dfs(int x,int y)
{
	if(res>=g-k) 
	{
		bj=true;
		return;
	}
	
	int xx=x,yy=y;
	for(int i=0;i<4;i++)
	{
		xx=x+dir[i][0];
		yy=y+dir[i][1];
		if(xx<1||yy<1||xx>n||yy>m||str[xx][yy]=='#'||vis[xx][yy])
			continue;
		vis[xx][yy]=true;
		res++;
		dfs(xx,yy);
		if(bj) break;
	}
	
} 

int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		scanf("%s",str[i]+1);
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(str[i][j]=='.')
				g++;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			if(str[i][j]=='.')
				if(!bj)
				{
					res=1;
					memset(vis,0,sizeof vis);
					vis[i][j]=true;
					dfs(i,j);
					if(bj) break;
				}
		if(bj) break;	
	}
	
	int cnt=0;
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(str[i][j]=='#')
				printf("%c",str[i][j]);
			else if(vis[i][j])
				printf("%c",str[i][j]);
			else 
			{
				if(cnt<k) printf("X");
				else printf("%c",str[i][j]);
				cnt++;
			}
		}
		puts("");		
	}

					
	
	return 0;
}
发布了43 篇原创文章 · 获赞 1 · 访问量 1586

猜你喜欢

转载自blog.csdn.net/DaNIelLAk/article/details/104149672