一.题目链接:

ZOJ-3478

二.题目大意:

给你一个 10 × 15 的图,图中包括以下符号.

'H' :终点

'X' :墙

'O' :蜘蛛网

'.' :空地

再给出两只异性企鹅各自的起点坐标.

只可以选取一只企鹅进行操作.

一只企鹅进行运动时,另一只企鹅的运动与这只企鹅左右对称运动.

企鹅运动无限制,当企鹅要走进墙时,则这只企鹅不动.

当一只企鹅走进蜘蛛网时,此企鹅不再移动.

直到另一只企鹅到达 此企鹅 的临方格并花费 11 点时间,才可以将此企鹅救到另一只企鹅的位置.

普通移动时,花费 5 时间.

当操作企鹅被困时,移动花费 3 时间.

当非操作企鹅被困时,移动花费 2 时间.

问两只企鹅是否能走到终点

如果不能,则输出 -1

否则,输出最小花费时间.

三.分析:

BFS + 优先队列优化 + 松弛原理 即可

注意:当此企鹅被困在蜘蛛网时,另一只企鹅即使与此企鹅相邻,也并一定要将此企鹅救出来 因为这里一直WA

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int inf = 0x3f3f3f3f;

struct node
{
    int x1, y1;
    int x2, y2;
    int step;
};

char mp[20][20];
int vis[20][20][20][20];
int Move[2][4][2] = {-1, 0, 1, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 1, 0, -1};

struct cmp
{
    bool operator()(node a, node b)
    {
        return a.step > b.step;
    }
};

node fun(node cur, int dir, int i)
{
    node tmp = cur;
    if(dir == 1)
    {
        tmp.x2 += Move[1][i][0];
        tmp.y2 += Move[1][i][1];
        if(tmp.x2 < 0 || tmp.x2 >= 10 || tmp.y2 < 0 || tmp.y2 >= 15 || mp[tmp.x2][tmp.y2] == 'X')
            tmp = cur;
        return tmp;
    }
    else if(dir == 2)
    {
        tmp.x1 += Move[0][i][0];
        tmp.y1 += Move[0][i][1];
        if(tmp.x1 < 0 || tmp.x1 >= 10 || tmp.y1 < 0 || tmp.y1 >= 15 || mp[tmp.x1][tmp.y1] == 'X')
            tmp = cur;
        return tmp;
    }
    else if(dir == 3)
    {
        tmp.x1 += Move[0][i][0];
        tmp.y1 += Move[0][i][1];
        tmp.x2 += Move[1][i][0];
        tmp.y2 += Move[1][i][1];
        if(tmp.x1 < 0 || tmp.x1 >= 10 || tmp.y1 < 0 || tmp.y1 >= 15 || mp[tmp.x1][tmp.y1] == 'X')
        {
            tmp.x1 = cur.x1;
            tmp.y1 = cur.y1;
        }
        if(tmp.x2 < 0 || tmp.x2 >= 10 || tmp.y2 < 0 || tmp.y2 >= 15 || mp[tmp.x2][tmp.y2] == 'X')
        {
            tmp.x2 = cur.x2;
            tmp.y2 = cur.y2;
        }
        return tmp;
    }
}

int bfs(node cur)
{
    memset(vis, -1, sizeof(vis));
    cur.step = 0;
    vis[cur.x1][cur.y1][cur.x2][cur.y2] = 1;
    priority_queue <node, vector<node>, cmp> q;
    q.push(cur);
    node p, t;
    while(!q.empty())
    {
        p = q.top();
        q.pop();
        if(p.x1 == p.x2 && p.y1 == p.y2 && mp[p.x1][p.y1] == 'H')
            return p.step;
        if(mp[p.x1][p.y1] == 'O' && mp[p.x2][p.y2] == 'O')
            continue;
        if(mp[p.x1][p.y1] == 'O')
        {
            if((int)abs(p.x1 - p.x2) + (int)abs(p.y1 - p.y2) == 1)
            {
                t = p;
                t.x1 = t.x2;
                t.y1 = t.y2;
                t.step += 11;
                if(vis[t.x1][t.y1][t.x2][t.y2] == -1 || vis[t.x1][t.y1][t.x2][t.y2] > t.step)
                {
                    vis[t.x1][t.y1][t.x2][t.y2] = t.step;
                    q.push(t);
                }
            }
            for(int i = 0; i < 4; ++i)
            {
                t = p;
                t = fun(t, 1, i);
                t.step += 3;
                if(vis[t.x1][t.y1][t.x2][t.y2] == -1 || vis[t.x1][t.y1][t.x2][t.y2] > t.step)
                {
                    vis[t.x1][t.y1][t.x2][t.y2] = t.step;
                    q.push(t);
                }
            }
        }
        else if(mp[p.x2][p.y2] == 'O')
        {
            if((int)abs(p.x1 - p.x2) + (int)abs(p.y1 - p.y2) == 1)
            {
                t = p;
                t.x2 = t.x1;
                t.y2 = t.y1;
                t.step += 11;
                if(vis[t.x1][t.y1][t.x2][t.y2] == -1 || vis[t.x1][t.y1][t.x2][t.y2] > t.step)
                {
                    vis[t.x1][t.y1][t.x2][t.y2] = t.step;
                    q.push(t);
                }
            }
            for(int i = 0; i < 4; ++i)
            {
                t = p;
                t = fun(t, 2, i);
                t.step += 2;
                if(vis[t.x1][t.y1][t.x2][t.y2] == -1 || vis[t.x1][t.y1][t.x2][t.y2] > t.step)
                {
                    vis[t.x1][t.y1][t.x2][t.y2] = t.step;
                    q.push(t);
                }
            }
        }
        else
        {
            for(int i = 0; i < 4; ++i)
            {
                t = p;
                t = fun(t, 3, i);
                t.step += 5;
                if(vis[t.x1][t.y1][t.x2][t.y2] == -1 || vis[t.x1][t.y1][t.x2][t.y2] > t.step)
                {
                    vis[t.x1][t.y1][t.x2][t.y2] = t.step;
                    q.push(t);
                }
            }
        }
    }
    return inf;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        for(int i = 0; i < 10; ++i)
        {
            getchar();
            for(int j = 0; j < 15; ++j)
                scanf("%c", &mp[i][j]);
        }
        struct node cur;
        scanf("%d %d %d %d", &cur.x1, &cur.y1, &cur.x2, &cur.y2);
        getchar();
        cur.x1--;
        cur.y1--;
        cur.x2--;
        cur.y2--;
        int ans1 = bfs(cur);
        swap(cur.x1, cur.x2);
        swap(cur.y1, cur.y2);
        int ans2 = bfs(cur);
        int ans = min(ans1, ans2);
        if(ans == inf)
            printf("-1\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}