题链
Description
给一张方格图,对于上下移动无限制,左右移动数分别不能超过L,R,求能到多少点。
Sol
发现 新的y坐标=老坐标-左移操作数+右移操作数
所以我们只需最小化左移操作数即可,最短路。
Code
#include<bits/stdc++.h> #define N 2007 #define pii pair<int,int> #define fi first #define se second using namespace std; char p[N][N]; pii X; int dx[4]={0,1,-1,0},dy[4]={1,0,0,-1}; int in[N][N],ans,cao[N][N],gao; template<class T> inline void read(T &x){ static char c; for (c=getchar();!isdigit(c);c=getchar()); for (x=0;isdigit(c);c=getchar())x=x*10+c-48; } int n,m,l,r,x,y; deque<pii> Q; signed main() { // freopen("2.txt","r",stdin); read(n); read(m); read(x); read(y); read(l); read(r); memset(cao,0x12,sizeof cao); for (int i=1;i<=n;i++) scanf("%s",p[i]+1); Q.push_back(pii(x,y)); in[x][y]=1; cao[x][y]=0; while (!Q.empty()) { X=Q.front(); Q.pop_front(); in[X.fi][X.se]=0; if (cao[X.fi+dx[0]][X.se+dy[0]]>cao[X.fi][X.se]+1 &&p[X.fi+dx[0]][X.se+dy[0]]=='.') { cao[X.fi+dx[0]][X.se+dy[0]]=cao[X.fi][X.se]+1;//to right if (!in[X.fi+dx[0]][X.se+dy[0]]) { in[X.fi+dx[0]][X.se+dy[0]]=1, Q.push_back(pii(X.fi+dx[0],X.se+dy[0])); } } for (int i=1;i<4;i++) if (cao[X.fi+dx[i]][X.se+dy[i]]>cao[X.fi][X.se] &&p[X.fi+dx[i]][X.se+dy[i]]=='.'){ cao[X.fi+dx[i]][X.se+dy[i]]=cao[X.fi][X.se];//to right if (!in[X.fi+dx[i]][X.se+dy[i]]) { in[X.fi+dx[i]][X.se+dy[i]]=1, Q.push_back(pii(X.fi+dx[i],X.se+dy[i])); } } } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { // if (p[i][j]=='*') continue; if (cao[i][j]>0x12121211) continue; gao=-(j-y-cao[i][j]); // to left if (gao<=l&&cao[i][j]<=r) ans++; } printf("%d ",ans); return 0; }