Codeforces1214D. Treasure Island (dp + Hash)

Posted lubixiaosi-zhaocao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1214D. Treasure Island (dp + Hash)相关的知识,希望对你有一定的参考价值。

题目链接:传送门


 

思路:

仔细观察可以发现,答案最多就是2,只要把(2,1)和(1,2)堵住就可以了。

答案是0的情况就是初始状态下,(1,1)就已经不可达(n,m)了,很好判断。

所以重点就是区分答案为1和答案为2的情况。

如果答案为1的话,就说明从(1,1)到(n,m)的所有路径都经过同一个点(这样的点至少一个)。

实际上,求出(1,1)出发可达的所有点的集合S1,和所有可达(n,m)的点S2。这里用dp来跑可以O(nm)。其中坐标要压成一维的(因为n、m的范围没有给出),否则不好开内存。

再以到(1,1)的曼哈顿距离相同为条件,把两个点集划分成O(n+m)个集合。

这些集合的大小的最小值,就是答案。


 

代码:O(nm)

技术图片
#include <bits/stdc++.h>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define N 1000005
#define INF 0x3f3f3f3f
#define mk(x) (1<<x) // be conscious if mask x exceeds int
#define sz(x) ((int)x.size())
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mp(a,b) make_pair(a, b)
#define endl ‘\n‘
#define lowbit(x) (x&-x)

using namespace std;
typedef long long ll;
typedef double db;

int n, m;
inline int getx(int t) 
    return t / m;

inline int gety(int t) 
    return t % m;

inline int gett(int x, int y) 
    return x*m + y;


char s[N];
bool vis11[N], visnm[N];
int main()

    cin >> n >> m;
    memset(vis11, false, sizeof vis11);
    memset(visnm, false, sizeof visnm);
    for (int i = 0; i < n; i++)
        scanf("%s", s + i*m);
    vis11[0] = visnm[n*m-1] = true;
    for (int t = 1; t < n*m-1; t++) 
        int x = getx(t), y = gety(t);
        if (s[t] == #) continue;
        if (x == 0) 
            int pret = gett(x, y-1);
            vis11[t] = vis11[pret];
        
        else if (y == 0) 
            int pret = gett(x-1, y);
            vis11[t] = vis11[pret];
        
        else 
            int pret1 = gett(x, y-1);
            int pret2 = gett(x-1, y);
            vis11[t] = vis11[pret1] || vis11[pret2];
        
    
    for (int t = n*m-2; t > 0; t--) 
        int x = getx(t), y = gety(t);
        if (s[t] == #)
            continue;
        if (x == n-1) 
            int pret = gett(x, y+1);
            visnm[t] = visnm[pret];
        
        else if (y == m-1) 
            int pret = gett(x+1, y);
            visnm[t] = visnm[pret];
        
        else 
            int pret1 = gett(x, y+1);
            int pret2 = gett(x+1, y);
            visnm[t] = visnm[pret1] || visnm[pret2];
        
    
    int ans = 2;
    for (int d = 1; d < n+m-2; d++) 
        int x = 0, y = d;
        if (y >= m) 
            y = m-1;
            x = d-y;
        
        int cnt = 0;
        for (; x < n && y >= 0; x++, y--) 
            int tmpt = gett(x, y);
            if (vis11[tmpt] && visnm[tmpt])
                cnt++;
        
        if (cnt == 0) 
            ans = 0;
            break;
        
        if (cnt == 1)
            ans = 1;
    
    cout << ans << endl;
    return 0;
View Code

 

以上是关于Codeforces1214D. Treasure Island (dp + Hash)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 505C Mr. Kitayuta, the Treasure Hunter(dp)

Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises), problem: (D) Treasure Is

Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

codeforces 505C - Mr. Kitayuta, the Treasure Hunter(dp)

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

codeforces 494a//Treasure// Codeforces Round #282(Div. 1)