【CodeForces】CF377A Maze

该博客讨论了一种编程竞赛中的问题,即如何在不破坏一个由空地和墙组成的四连通迷宫的连通性的情况下,将指定数量的空地转换为墙。这个问题可以通过深度优先搜索(DFS)策略来解决,确保所有空地仍然在一个连通区域。代码示例给出了一个使用DFS实现的解决方案,其时间复杂度为O(mn),其中m和n分别为迷宫的宽度和高度。该方法在给定条件下保证至少存在一个解,并且允许输出多种可行解。
摘要由CSDN通过智能技术生成

题目地址:

https://www.luogu.com.cn/problem/CF377A

题面翻译:
题目描述:
小P非常的喜欢方格迷宫。方格迷宫是一个 n × m n\times m n×m的由墙和空地构成的长方形方阵。只有当两点满足四联通条件时才能走过去。

小P画了一个迷宫,里面所有的空地都是四连通的。但闲着没事干的小P认为自己画的迷宫里小墙太多了很难看,所以他希望能够通过把迷宫中k个格子从空地变成墙但不破坏整张图的连通性(即仍然保持所有空地在一个四连通块中)。但是小P太蠢了做不来,请你帮助他。

输入:
第一行 n , m , k n,m,k n,m,k(描述如题)
第二到 n + 1 n+1 n+1行:
每行 m m m个字符,分别是’.‘或’#'。 '.‘表示空地,’#‘表示墙。
输出:
把整张图原样打出来,但是被你修改的格子输出’X’。

题目描述:
Pavel loves grid mazes. A grid maze is an n × m n×m 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 k k empty cells into walls so that all the remaining cells still formed a connected area. Help him.

输入格式:
The first line contains three integers n n n , m m m , k k k ( 1 ≤ n , m ≤ 500 1\le n,m\le 500 1n,m500 , 0 ≤ k ≤ s 0\le k\le s 0ks), where n n n and m m m are the maze’s height and width, correspondingly, k k k is the number of walls Pavel wants to add and letter s s s represents the number of empty cells in the original maze.

Each of the next n n n lines contains m m 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.

输出格式:
Print n n n lines containing m m 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.

可以用DFS,遍历矩阵,当遍历到空地的时候,如果 k k k个造墙指标还没有用掉,则开始DFS,回溯的时候将空地变成新墙,这样就能保证空地仍然连通。代码如下:

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

const int N = 510;
int n, m, k, cnt;
int d[] = {-1, 0, 1, 0, -1};
char a[N][N];
bool vis[N][N];

void dfs(int x, int y) {
  vis[x][y] = true;
  for (int i = 0; i < 4; i++) {
    int nx = x + d[i], ny = y + d[i + 1];
    if (0 <= nx && nx < n && 0 <= ny && ny < m && !vis[nx][ny] && a[nx][ny] != '#')
      dfs(nx, ny);
  }

  if (cnt) {
    a[x][y] = 'X';
    cnt--;
  }
}

int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < n; i++)
    scanf("%s", a[i]);
  
  cnt = k;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (cnt && a[i][j] == '.') {
        memset(vis, 0, sizeof vis);
        dfs(i, j);
      }
  
  for (int i = 0; i < n; i++)
    puts(a[i]);
}

时空复杂度 O ( m n ) O(mn) O(mn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值