ABC400D题解

很简单,就是用类似 \(\operatorname{BFS}\) 的方法进行维护,走路不花费,前踢花费 \(1\),不过这个题很显然两种不同的操作无法满足 \(\operatorname{BFS}\) 的性质,所以得使用优先队列进行维护。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
char a[N][N];
int d[N][N];
struct node
{
    int x;
    int y;
    int cnt;
    bool operator<(const node&a)const
    {
        return cnt>a.cnt;
    }
};
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};
signed main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i = 1;i<=n;i++)
    {
        scanf("%s",a[i]+1);
    }
    int A,B,C,D;
    scanf("%d %d %d %d",&A,&B,&C,&D);
    memset(d,0x3f,sizeof(d));
    d[A][B] = 0;
    priority_queue<node>q;
    q.push({A,B,0});
    while(q.size())
    {
        node num = q.top();
        q.pop();
        int cnt = num.cnt;
        int x = num.x;
        int y = num.y;
        if(x == C&&y == D)
        {
            printf("%d",num.cnt);
            return 0;
        }
        for(int i = 0;i<4;i++)
        {
            int r = x+dx[i];
            int c = y+dy[i];
            if(r>=1&&c>=1&&r<=n&&c<=m&&num.cnt<d[r][c]&&a[r][c] == '.')
            {
                d[r][c] = cnt;
                q.push({r,c,cnt});
            }
        }
        for(int i = 0;i<4;i++)
        {
            for(int j = 1;j<=2;j++)
            {
                int r = x+dx[i]*j;
                int c = y+dy[i]*j;
                if (r>=1&&c>=1&&r<=n&&c<=m)
                {
                    if(a[r][c] == '#'&&d[r][c]>cnt+1)//需要d数组记录
                    {
                        d[r][c] = cnt+1;
                        q.push({r,c,cnt+1});//前踢之后顺便走个路
                    }
                }
                else
                {
                    break;//退出,可要可不要,简单常数优化
                }
            }
        }
    }
    printf("-1");
    return 0;
}
posted @ 2025-05-03 11:45  林晋堃  阅读(14)  评论(0)    收藏  举报