欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces Round #583 (Div. 1 + Div. 2,) D. Treasure Island(dfs+思维)

程序员文章站 2022-07-07 22:56:25
...

题目链接
Codeforces Round #583 (Div. 1 + Div. 2,) D. Treasure Island(dfs+思维)
Codeforces Round #583 (Div. 1 + Div. 2,) D. Treasure Island(dfs+思维)
题意:要你从(1,1)走到(n,m),你只能往下和往右走,问最少要设置多少障碍才能使你走不动(n,m)
思路:答案最多为2,以为只要堵住(1,1)的下边和右边你就走不了了,那么能不能更少呢?其实有的,就是从起点到终点的众多路径中如果存在着必经点的话,那么答案就是1,现在关键是怎么判断是否存在必经点,可以用dfs标记一下路径,如果存在着两个完全不相同的路径那么答案就是2,否则就是1.

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+1;
char s[maxn];
int n,m,vis[maxn],ans,dir[2][2]={1,0,0,1};
void dfs(int x)
{
	if(ans) return ;
	if(x==(n*m-1)) {
		ans++;return ;
	}
	int X=x/m,Y=x%m;
	for(int i=0;i<2;++i)
	{
		int tx=X+dir[i][0],ty=Y+dir[i][1];
		if(tx>=n||ty>=m||vis[tx*m+ty]) continue;
		vis[tx*m+ty]=1;
		dfs(tx*m+ty);
		if(ans) return ;
	}
} 
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;++i)
	{
		scanf("%s",s+i*m);
		for(int j=i*m;j<(i+1)*m;++j)
		if(s[j]=='#') vis[j]=1; 
	}
	vis[0]=1,ans=vis[n*m-1]=0;
	dfs(0);
	if(!ans){
		puts("0");return 0;
	}
	vis[0]=1,ans=vis[n*m-1]=0;
	dfs(0);
	printf("%d\n",ans?2:1);
}