Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) B

题链

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\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/rrsb/p/9807211.html