题目可以转换成 "能否找到两条从起点到终点无重复格子的路径(起点和终点可以重复)"。
可以写个记忆化搜索,搜索两次,第一次搜索后把第一次的路径除了起点和终点标记为 墙。然后再搜索一次看看有没有第二条路径。如果有则"YES" 否则 "NO"
具体看代码 时间复杂度 O(N)
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N = 1e6 + 10;
int dp[4][N];
bool v[4][N];//为 true说明这个点没有路径可以继续往下走到终点
bool dfs(int x,int y){
if(x > n || y > 3){
cout << "fds " << " " << x << " " << y <<
endl;
return 0;
}
if(x == n && y == 3)
return 1;
if(v[y][x]) return 0;//已经确定在这个点没有路径
if(x < n && dp[y][x + 1] == 0)//向下走能走且不是墙
{
dp[y][x + 1] = 1;//标记这个点为路径上的点
if(dfs(x + 1,y))//找到路径
return 1;
v[y][x + 1] = 1;// 标记这个点没有路径
dp[y][x + 1] = 0;//这个点没有路径,取消标记
}
if(y < 3 && dp[y + 1][x] == 0)//向右走能走且不是墙
{
dp[y + 1][x] = 1;//标记这个点为路径上的点
if(dfs(x,y + 1))//找到路径
return 1;
v[y + 1][x] = 1;// 标记这个点没有路径
dp[y + 1][x] = 0;//这个点没有路径,取消标记
}
return 0;
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; ++i){
int x,y; cin >> y >> x;
dp[y][x] = 1;//标记墙
}
if(dfs(1,1)){//第一次可以找到路径
dp[1][1] = dp[3][n] = 0;
memset(v,0,sizeof v);
if(dfs(1,1))//第二次也能找到路径
{ cout << "YES" ; return 0; }
}
cout << "NO" ;
return 0;
}
京公网安备 11010502036488号