BZOJ 1967 [Ahoi2005]CROSS 穿越磁场

啊。。比较水的一题。先离散化,然后直接跑一遍最短路就可以了。

注意它可以从离散化后的边缘走。。因此要处理一下边缘(可以看我代码,代码中用注释标注了)。。因为这个WA了一发

 

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const size_t Max_N(105);
typedef pair<int, int> pil;

const int dx[] = {+1, -1, +0, +0};
const int dy[] = {+0, +0, +1, -1};

struct square
{
    int sx, sy, tx, ty;
};

int N;
square V[Max_N];
int SX, SY, TX, TY;
int A, B;
double X[Max_N * 3], Y[Max_N * 3];

bool Map[Max_N * 3][Max_N * 3];

int lookup(const int &n, const double Array[], const double &Key)
{
    int l(1), r(n + 1), mid;
    while (l < r)
    {
        mid = l + ((r - l) >> 1);
        if (Array[mid] == Key)
            return mid;
        if (Array[mid] < Key)
            l = mid + 1;
        else
            r = mid;
    }
    return -1;
}

void init()
{
    int C;
    scanf("%d", &N);
    for (int i = 1;i <= N;++i)
    {
        scanf("%d%d%d", &V[i].sx, &V[i].sy, &C);
        V[i].tx = V[i].sx + C, V[i].ty = V[i].sy + C;
        X[i * 3 - 2] = V[i].sx, X[i * 3 - 1] = V[i].tx, X[i * 3] = (V[i].sx + V[i].tx) / 2.0;
        Y[i * 3 - 2] = V[i].sy, Y[i * 3 - 1] = V[i].ty, Y[i * 3] = (V[i].sy + V[i].ty) / 2.0;
    }
    scanf("%d%d%d%d", &SX, &SY, &TX, &TY);
    X[N * 3 + 1] = SX, X[N * 3 + 2] = TX, X[N * 3 + 3] = (SX + TX) / 2.0;
    Y[N * 3 + 1] = SY, Y[N * 3 + 2] = TY, Y[N * 3 + 3] = (SY + TY) / 2.0;
}

void make_graph()
{
    sort(X + 1, X + 1 + N * 3 + 3);
    sort(Y + 1, Y + 1 + N * 3 + 3);
    A = (unique(X + 1, X + 1 + N * 3 + 3) - X) - 1;
    B = (unique(Y + 1, Y + 1 + N * 3 + 3) - Y) - 1;
    for (int i = 1;i <= N;++i)
    {
        V[i].sx = lookup(A, X, V[i].sx * 1.0), V[i].sy = lookup(B, Y, V[i].sy * 1.0);
        V[i].tx = lookup(A, X, V[i].tx * 1.0), V[i].ty = lookup(B, Y, V[i].ty * 1.0);
    }
    SX = lookup(A, X, SX * 1.0), SY = lookup(B, Y, SY * 1.0);
    TX = lookup(A, X, TX * 1.0), TY = lookup(B, Y, TY * 1.0);
    for (int i = 1;i <= N;++i)
    {
        for (int j = V[i].sy;j <= V[i].ty;++j)
            Map[V[i].sx][j] = Map[V[i].tx][j] = true;
        for (int j = V[i].sx;j <= V[i].tx;++j)
            Map[j][V[i].sy] = Map[j][V[i].ty] = true;
    }
}

int Dist[Max_N * 3][Max_N * 3];
bool In_Q[Max_N * 3][Max_N * 3];

void SPFA()
{
    ++A, ++B;//处理边缘
    memset(Dist, 0X3F, sizeof(Dist));
    queue<pil> Q;
    Q.push(make_pair(SX, SY));
    Dist[SX][SY] = 0, In_Q[SX][SY] = true;
    int TopX, TopY, ToX, ToY;
    while (Q.size())
    {
        TopX = Q.front().first, TopY = Q.front().second;
        In_Q[TopX][TopY] = false;
        Q.pop();
        for (int k = 0;k != 4;++k)
        {
            ToX = TopX + dx[k], ToY = TopY + dy[k];
            if (!(ToX >= 1 && ToX <= A && ToY >= 1 && ToY <= B))
                continue;
            if (Dist[ToX][ToY] > Dist[TopX][TopY] + Map[ToX][ToY])
            {
                Dist[ToX][ToY] = Dist[TopX][TopY] + Map[ToX][ToY];
                if (!In_Q[ToX][ToY])
                {
                    In_Q[ToX][ToY] = true;
                    Q.push(make_pair(ToX, ToY));
                }
            }
        }
    }
    printf("%d", Dist[TX][TY]);
}

int main()
{
    init();
    make_graph();
    SPFA();
    return 0;
}
BZOJ 1967

 

你可能感兴趣的:(BZOJ 1967 [Ahoi2005]CROSS 穿越磁场)