cf 583 D Treasure Island (dfs)

题目链接点这里
All of us love treasures, right? That’s why young Vasya is heading for a Treasure Island.
Treasure Island may be represented as a rectangular table n×m which is surrounded by the ocean. Let us number rows of the field with consecutive integers from 1 to n from top to bottom and columns with consecutive integers from 1 to m from left to right. Denote the cell in r-th row and c-th column as (r,c). Some of the island cells contain impassable forests, and some cells are free and passable. Treasure is hidden in cell (n,m).
Vasya got off the ship in cell (1,1). Now he wants to reach the treasure. He is hurrying up, so he can move only from cell to the cell in next row (downwards) or next column (rightwards), i.e. from cell (x,y) he can move only to cells (x+1,y) and (x,y+1). Of course Vasya can’t move through cells with impassable forests.
Evil Witch is aware of Vasya’s journey and she is going to prevent him from reaching the treasure. Before Vasya’s first move she is able to grow using her evil magic impassable forests in previously free cells. Witch is able to grow a forest in any number of any free cells except cells (1,1) where Vasya got off his ship and (n,m) where the treasure is hidden.
Help Evil Witch by finding out the minimum number of cells she has to turn into impassable forests so that Vasya is no longer able to reach the treasure.
Input
First line of input contains two positive integers n, m (3≤n⋅m≤1000000), sizes of the island.
Following n lines contains strings si of length m describing the island, j-th character of string si equals “#” if cell (i,j) contains an impassable forest and “.” if the cell is free and passable. Let us remind you that Vasya gets of his ship at the cell (1,1), i.e. the first cell of the first row, and he wants to reach cell (n,m), i.e. the last cell of the last row.
It’s guaranteed, that cells (1,1) and (n,m) are empty.
Output
Print the only integer k, which is the minimum number of cells Evil Witch has to turn into impassable forest in order to prevent Vasya from reaching the treasure.
Examples
inputCopy
2 2


outputCopy
2
inputCopy
4 4

#.#.

.#…
output
1
input
3 4

.##.

output
2
Note
The following picture illustrates the island in the third example. Blue arrows show possible paths Vasya may use to go from (1,1) to (n,m). Red illustrates one possible set of cells for the Witch to turn into impassable forest to make Vasya’s trip from (1,1) to (n,m) impossible.

题意:一个地图n行m列,已知宝藏在(n,m)处,V开始在(1,1),他想到达(n,m)处,途中.为能走的路,#不能走,EW想阻止V寻得宝藏,可以用魔法将某些.变成#以达到目的,问EW达到目的,使用魔法的最少次数。
解析:不难想到魔法的最大次数为2,即把入口(1,2)和(2,1)堵了,或把出口(n-1,m)和(n,m-1)堵了。所以共三种情况:

(1)魔法次数为0,V一开始就到不了(n,m);
(2)魔法次数为1,V到达(n,m)的路有多条,但这些路径都会经过一个点(x,y),这个点可能有多个,但只要堵其中的任意一个,这些路都会变得不可行。
(3)魔法次数为2,V到达(n,m)的路有多条,但不存在(2)情况的点(x,y),这时EW只能堵掉出口或入口。
综述,我们可以两遍dfs,第一遍的时候把跑过的点都标记了,这样那些必经点就被堵了,如果不能跑到(n,m)说明是情况(1),第二遍dfs如果还能跑到(n,m)说明是情况(3),若不然,则是情况(2)。

需要注意的坑:

(1)题目说n×m<=1e6,所以不能简单的用二维,要压缩成一维.
(2)两次dfs前都要保证(n,m)未被标记,(1,1)被标记.

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
#define faster ios::sync_with_stdio(0),cin.tie(0)
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
int n,m,ans;
bool vis[maxn];
char s[maxn];
void dfs(int x,int y){
    if(ans)return;
    if(x==n-1&&y==m-1){
        ans++;return;
    }
    if(x+1<n&&!vis[(x+1)*m+y]){
        vis[(x+1)*m+y]=1;dfs(x+1,y);
    }
    if(ans)return;
    if(y+1<m&&!vis[x*m+y+1]){
        vis[x*m+y+1]=1;dfs(x,y+1);
    }
}
int main()
{
    faster;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>s;
        for(int j=0;j<m;j++){
            if(s[j]=='#')vis[i*m+j]=1;
        }
    }
    vis[0]=1;vis[(n-1)*m+m-1]=0;
    dfs(0,0);
    if(ans==0)puts("0");
    else {
        ans=0;
        vis[0]=1;vis[(n-1)*m+m-1]=0;
        dfs(0,0);
        if(ans==0)puts("1");
        else puts("2");
    }
    return 0;
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值