Codeforces Round #516 (Div. 2)D. Labyrinth

D. Labyrinth

题目链接:https://codeforces.com/contest/1064/problem/D

题意:

给出一个n*m的矩阵以及人物的起点,并且给出x,y,分别代表这个人向左最多走x步,向右最多走y步。

矩阵中存在障碍,问这个人最多能到达多少数量的格子。

题解:

就是一个bfs...只是要稍微剪枝一下,如果发现当前这个点所到达的格子已经被之前的一个点到达过,当且仅当当前点的x或y至少一个比之前到达的点大时,就将这个点入队。

只有这样才能保证解最优。

代码如下:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 2005 ;
int n,m,R,C;
int mp[N][N],vis[N][N][2],l[N][N],r[N][N],check[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
int ans = 1;
char s[N];
bool ok(int x,int y){
    if(x>=1 && x<=n && y>=1 && y<=m && mp[x][y]!=2) return true;
    return false ;
}
struct node{
    int x,y,lx,ly;
}cur;
queue <node> q;
void bfs(){
    while(!q.empty()){
        node now = q.front();q.pop();
        int x = now.x,y = now.y,l,r;
        for(int i=0;i<4;i++){
            cur.x=x+dx[i];cur.y=y+dy[i];
            l = now.lx;r = now.ly;
            if(i==2) r--;
            if(i==3) l--;
            if(ok(cur.x,cur.y)&&r>=0&&l>=0){
                if(l>vis[cur.x][cur.y][0]||r>vis[cur.x][cur.y][1]){
                    if(vis[cur.x][cur.y][0]==-1) ans++;
                    q.push(node{cur.x,cur.y,l,r});
                    vis[cur.x][cur.y][0]=l;
                    vis[cur.x][cur.y][1]=r;
                }
            }
        }
    }
}
int main(){
    int x,y;
    cin>>n>>m>>R>>C>>x>>y;
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        for(int j=0;j<m;j++){
            if(s[j]=='.') mp[i][j+1]=1;
            else mp[i][j+1]=2;
        }
    }
    q.push(node{R,C,x,y});
    memset(vis,-1,sizeof(vis));
    vis[R][C][0]=x;vis[R][C][1]=y;
    check[R][C]=1;
    bfs();
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/heyuhhh/p/10181188.html