题目:https://codeforces.com/contest/1214/problem/D
思路:首先判断出最多填两个格子(把(1,1)向下的向右的格子都堵上),最少不用填(原图走不通的情况),所以题目转换为是否有一个格子被一切(1,1)到(n,m)的路径经过,而题目dfs做法的关键点在于由于在一个格子只能向下或者向右移动,所以从(1,1)移动到(x,y)的步数是固定的,所以花费几步能走到的点都是固定的,所以如果在某一步只有一个点可以走,那么说明答案为1,否则为2.
于是用dfs记录最后能到达(n,m)的点以及花几步能到达即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
string s[maxn];
int vis[maxn];
int dx[] = {0 , 1} , dy[] = {1 , 0};
int n , m , mm;
vector <int> v[maxn];
void dfs(int u , int d) {
if(u == n * m - 1) {
vis[u] = 2; return;
}
mm = max(mm , d);
vis[u] = 1;
bool flag = 0;
for(int i = 0 ; i < 2 ; i++) {
int x = u / m + dx[i] , y = u % m + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m && s[x][y] == '.') {
if(!vis[x * m + y]) {
dfs(x * m + y , d + 1);
if(vis[x * m + y] == 2) {
flag = 1;
}
}
else if(vis[x * m + y] == 2) {
flag = 1;
}
}
}
if(flag) {
vis[u] = 2;
v[d].push_back(u);
}
}
int main() {
ios::sync_with_stdio(0);
cin >> n >> m;
for(int i = 0 ; i < n ; i++) {
cin >> s[i];
}
mm = 0;
dfs(0 , 0);
if(vis[n * m - 1] != 2)cout << 0 << "\n";
else {
bool flag = 0;
for(int i = 1 ; i <= mm ; i++) {
if(v[i].size() <= 1) {
flag = 1 ;
break;
}
}
if(flag)cout << 1 << "\n";
else cout << 2 << "\n";
}
return 0;
}

本文解析了Codeforces比赛中的D题,通过深度优先搜索(DFS)算法,探讨了如何判断在给定的网格中,从起点到终点最少需要堵住几个格子才能使得路径唯一。文章详细介绍了算法思路及实现代码。
470

被折叠的 条评论
为什么被折叠?



