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;
以上是关于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