抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

题目传送门

题意

给定一个 \(n\times m\) 的地图,每个格子要么是障碍,要么是空格。你可以把除 \((1,1)\)\((n,m)\) 外的若干个格子变成障碍,求使得 \((1,1)\)\((n,m)\) 没有路径最少需要把几个格子变成障碍。

\(3\le n\cdot m\le 10^6\)

题解

答案只可能是 \(0,1,2\) 中的一种。

\(0\) 可以直接判;\(1\) 就是 \((1,1)\) 能走到 \((n,m)\) 但必须都经过某个格子 \((x,y)\);否则就是 \(2\)

那么只要找出一条路径,若找不到就是 \(0\);然后再找一条强制不经过第一条路径中的点的路径,若找不到就是 \(1\);否则就是 \(2\)

吐槽一句:我一开始写了个求起点、终点到某个点的路径数量,然后用乘法原理判断,只可惜这东西要取模,于是愉快地 WA on 233 了(Submission #60334654

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <cstdio>
#include <cstdlib>
int n, m, a[1000005];
char t[1000005];
int get(int *a, int i, int j){
if (i < 1 || j < 1 || i > n || j > m) return 0;
return a[(i - 1) * m + j];
}
void set(int *a, int i, int j, int v){
a[(i - 1) * m + j] = v;
}
void GG(int x){
printf("%d\n", x), exit(0);
}
void dfs2(int i, int j){
if (i > n || j > m) return;
if ((i != 1 || (j != 1)) && get(a, i, j)) return;
if (i == n && j == m) GG(2);
set(a, i, j, 1);
dfs2(i + 1, j), dfs2(i, j + 1);
}
void dfs1(int i, int j){
if (i > n || j > m) return;
if ((i != 1 || (j != 1)) && get(a, i, j)) return;
if (i == n && j == m) dfs2(1, 1), GG(1);
set(a, i, j, 1);
dfs1(i + 1, j), dfs1(i, j + 1);
}
int main(){
scanf("%d%d", &n, &m);
for (register int i = 1; i <= n; ++i){
scanf("%s", t + 1);
for (register int j = 1; j <= m; ++j)
if (t[j] == '#') set(a, i, j, 1);
}
dfs1(1, 1), GG(0);
}

评论