CF337A Maze 解题报告
1 题目链接
2 题目大意
题目 : 迷宫
题目大意 : 给出一片
n
×
m
n \times m
n×m单元格,请输出一种构造方式,使得在将k
个空单元格改为墙壁之后,剩下的空单元格形成一个连通图。
3 解法分析
显然这是一个搜索题。
简单来说就是四个字 : 正难则反 (打死我我也不会说是暴搜不会)。那么,我们不妨用逆向思维来看看这道题,题目就变成选出
s
−
k
s-k
s−k个格子,使他们构成连通图。此时,我们便可以使用dfs(广度优先搜索)来解。设
d
f
s
(
x
,
y
)
dfs(x, y)
dfs(x,y)表示现在在
(
x
,
y
)
(x,y)
(x,y),那么每一次去寻找一个没有走过的点,直到大小为
s
−
k
s-k
s−k即可。
Dalao代码 #001
// From Heart_Blue
// Rating 2425
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MEM(a,b) memset((a),(b),sizeof(a))
const LL INF = 1e9 + 7;
const int N = 5e2 + 10;
char chess[N][N];
int flag[N][N];
int n, m;
int c;
int dx[] = { 0,0,-1,1 };
int dy[] = { -1,1,0,0 };
void dfs(int x, int y)
{
if (x < 0 || x >= n) return;
if (y < 0 || y >= m) return;
if (c == 0) return;
if (chess[x][y] == '#') return;
if (flag[x][y]) return;
flag[x][y] = 1;
c--;
for (int i = 0; i < 4; i++)
{
dfs(x + dx[i], y + dy[i]);
}
}//十分简单地向四周搜索
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int k;
int s = 0;
cin >> n >> m >> k;
int x, y;
x = -1, y = -1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> chess[i][j];
if (chess[i][j] == '.') s++, x = i, y = j;
}
}
c = s - k;
MEM(flag, 0);
dfs(x, y);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (chess[i][j] == '.')
{
if (flag[i][j]) putchar('.');
else putchar('X');
}
else putchar('#');
}
putchar('\n');
}
return 0;
}
Dalao代码 #002
// From ko_osaga
// Rating 3261
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
int n, m, s;
char str[555][555];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
bool vis[555][555];
vector<pi> ord;
void dfs(int x, int y){
if(vis[x][y] || str[x][y] == '#') return;
vis[x][y] = 1;
ord.push_back(pi(x, y));
for(int i=0; i<4; i++){
if(x + dx[i] < 0 || x + dx[i] >= n || y + dy[i] < 0 || y + dy[i] >= m) continue;
dfs(x + dx[i], y + dy[i]);
}
}//同上
int main(){
cin >> n >> m >> s;
for(int i=0; i<n; i++) cin >> str[i];
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(str[i][j] == '.'){
dfs(i, j);
reverse(ord.begin(), ord.end());
for(int k=0; k<s; k++){
str[ord[k].first][ord[k].second] = 'X';
}
for(int i=0; i<n; i++) cout << str[i] << endl;
return 0;
}
}
}
}
蒟蒻代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
char m[507][507];
int l, r, k;
void dfs(int x, int y) {
if (x < 0 || y < 0 || x >= l || y >= r)
return ;
if (m[x][y] == 'X')
if (k == 0)
return ;
else {
++k;
m[x][y] = '.';
dfs(x - 1, y);
dfs(x, y - 1);
dfs(x, y + 1);
dfs(x + 1, y);
}
}
int x, y;
int main() {
scanf("%d%d%d\n", &l, &r, &k);
for (register int i = 0; i < l; ++i) {
for (register int j = 0; j < r; ++j) {
scanf("%c", &m[i][j]);
if (m[i][j] == '.'){
--k;
m[i][j] = 'X';
x = i;
y = j;
}
}
getchar();
}
dfs(x, y);
for (register int i = 0; i < l; ++i)
printf("%s\n", m[i]);
return 0;
}//本蒟蒻的奇妙码风