题意:
给以一个网格图,有起点终点和一些怪兽,可以上下左右走,不能走到距离怪兽曼哈顿距离为d以内的地方,问到终点最短路径
n*m<=2e5,d<=2e5
思路:
因为n*m的范围,不能直接建2e5*2e5的图,所以要vector.resize()
如果对每个怪兽都预处理的话,复杂度将是O(d2)
所以我们可以让所有怪兽同时走,这样预处理只有O(nm),也可以证明不会漏情况
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 1e6+100; const int maxm = 1e6+100; //const int inf = 0x3f3f3f3f; const int inf = 1e9+7; const db pi = acos(-1.0); vector<char>a[maxn]; vector<int>v[maxn],vis[maxn],wall[maxn],tp[maxn]; int n,m,d; int dx[5] = {0,-1,0,1}; int dy[5] = {1,0,-1,0}; bool ck(int x, int y){ if(x>=1&&x<=n&&y>=1&&y<=m)return true; return false; } queue<pair<PI, int>>seetq; void seet(){ while(!seetq.empty()){ auto top = seetq.front(); seetq.pop(); int x = top.fst.fst; int y = top.fst.sc; int z = top.sc; //f(v[x][y])continue; //v[x][y]=1; if(z==d)continue; for(int i = 0; i < 4; i++){ if(ck(x+dx[i],y+dy[i])&&v[x+dx[i]][y+dy[i]]==0){ seetq.push({{x+dx[i],y+dy[i]},z+1}); v[x+dx[i]][y+dy[i]]=1; } } } return; } PI s,t; char str[maxn]; int main() { scanf("%d %d %d", &n, &m, &d); for(int i = 1; i <= n; i++){ v[i].resize(m+1); a[i].resize(m+1); vis[i].resize(m+1); wall[i].resize(m+1); tp[i].resize(m+1); } //getchar(); for(int i = 1; i <= n; i++){ scanf("%s",str+1); for(int j = 1; j <= m; j++){ v[i][j]=vis[i][j]=wall[i][j]=0; tp[i][j]=inf; char c = str[j]; a[i][j] = c; if(c=='S'){ s = {i,j}; } else if(c=='F'){ t = {i,j}; } else if(c=='M'){ wall[i][j]=d+1; seetq.push({{i,j},0}); v[i][j]=1; } } } seet(); queue<pair<PI,int>>q; q.push({{s.fst,s.sc},0}); int ans = -1; if(v[s.fst][s.sc]==1)return printf("-1"),0; q.push({{s.fst,s.sc},0}); while(!q.empty()){ auto top = q.front(); q.pop(); int x = top.fst.fst; int y = top.fst.sc; int z = top.sc; if(x==t.fst&&y==t.sc){ ans=z; break; } if(vis[x][y])continue; vis[x][y]=1; for(int i = 0; i < 4; i++){ int nx = x+dx[i]; int ny = y+dy[i]; if(ck(nx,ny)&&vis[nx][ny]==0&&v[nx][ny]!=1){ q.push({{nx,ny},z+1}); } } } printf("%d",ans); return 0; } /* 4 2 2 3 2 3 4 1 4 0 */