码迷,mamicode.com
首页 > 其他好文 > 详细

06-图4. Saving James Bond - Hard Version (30)

时间:2015-06-16 09:24:12      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:pat

该题的关键是题干最后一句:如果有不同的路线都是最短路,那么输出第一跳最短的路线。解决方法是把湖心小岛周围一圈的节点(即距离湖心小岛小于D的鳄鱼)看作起点,对这些起点依次调用无权最短路算法,找出路径最短(且相同)的那些起点,然后比较从湖心小岛到它们的距离,输出最小的距离所在的路径即可。


#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>

#define fuck cout << endl;
using namespace std;

struct Coordinate
{
    int x;
    int y;
};

bool operator==(Coordinate& a, Coordinate& b)
{
    return a.x == b.x && a.y == b.y;
}

float DistanceOfPoints(const Coordinate& a, const Coordinate& b)
{
    return sqrtf(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

void JudgePosition(const int& D, Coordinate* crocodile, const int& i, bool* isCloseToEdge, bool* isCloseToCenter)
{
    // 靠近湖岸
    if (crocodile[i].x >= 50 - D || crocodile[i].x <= -50 + D ||
        crocodile[i].y >= 50 - D || crocodile[i].y <= -50 + D)
    {
        isCloseToEdge[i] = true;
    }
    else
    {
        isCloseToEdge[i] = false;
    }
    // 靠近湖心小岛
    if ( sqrtf(pow(crocodile[i].x, 2) + pow(crocodile[i].y, 2)) <= 7.5 + D)
    {
        isCloseToCenter[i] = true;
    }
    else
    {
        isCloseToCenter[i] = false;
    }
}

bool IsCloseToEdge(const int& D, const Coordinate& crocodile)
{
    return (crocodile.x >= 50 - D || crocodile.x <= -50 + D ||
            crocodile.y >= 50 - D || crocodile.y <= -50 + D);
}

bool IsCloseToCenter(const int& D, const Coordinate& crocodile)
{
    return (sqrtf(pow(crocodile.x, 2) + pow(crocodile.y, 2)) <= 7.5 + D);
}


vector<int> UnweightedShortestWay(const int& s, vector<vector<int> >& graph, vector<Coordinate>& crocodile)
{
    Coordinate O;
    O.x = 0;
    O.y = 0;

    int minPath         = 9999;
    int minFirstHeap    = 9999;
    vector<int> bestPath;

    // 一共s个鳄鱼,s是湖心小岛,s+1是岸边
    for (int i = 0; i < graph[s].size(); i++)
    {
        bool isInitialFind  = true;

        float currentHeapDistance = DistanceOfPoints(O, crocodile[graph[s][i]]);

        vector<int> currentPath(s + 2, -1);

        vector<int> distance(s + 2, -1);
        distance[graph[s][i]] = 0;

        queue<int> nodeQueue;
        nodeQueue.push(graph[s][i]);

        while(!nodeQueue.empty())
        {
            bool isFind = false;
            int lastNode = nodeQueue.front();
            nodeQueue.pop();
            for (int j = 0; j < graph[lastNode].size(); j++)
            {
                // graph[lastNode][j]是和lastNode相连的节点的编号
                int currentNode = graph[lastNode][j];
                if (distance[currentNode] == -1)
                {
                    distance[currentNode] = distance[lastNode] + 1;
                    currentPath[currentNode] = lastNode;
                    if (currentNode == s + 1)
                    {
                        if (isInitialFind)
                        {
                            isInitialFind = false;
                            //minPath = distance[currentNode];
                        }
                        if (distance[currentNode] < minPath)
                        {
                            minPath = distance[currentNode];
                            minFirstHeap = currentHeapDistance;
                            bestPath = currentPath;
                        }
                        else if (distance[currentNode] == minPath)
                        {
                            if (currentHeapDistance < minFirstHeap)
                            {
                                minFirstHeap = currentHeapDistance;
                                bestPath = currentPath;
                            }
                        }
                    }
                    nodeQueue.push(currentNode);
                    if (!isInitialFind)
                    {
                        isFind = true;
                        break;
                    }
                }
            }
            if (isFind)
            {
                break;
            }
        }
    }
    return bestPath;
}


int main()
{
    int N;
    int D;
    scanf("%d %d", &N, &D);
    int nodeCount = N + 2;
    vector<vector<int> > graph(nodeCount);
    vector<Coordinate> crocodile(nodeCount);

    for (int i = 0; i < N; i++)
    {
        scanf("%d %d", &crocodile[i].x, &crocodile[i].y);
    }
    crocodile[N].x = 0;
    crocodile[N].y = 0;
    crocodile[N + 1].x = -1;
    crocodile[N + 1].y = -1;
    // 一共N个鳄鱼,N是湖心小岛,N+1是岸边
    for (int i = 0; i < N; i++)
    {
        if (IsCloseToCenter(D, crocodile[i]))
        {
            graph[i].push_back(N);
            graph[N].push_back(i);
        }
        if (IsCloseToEdge(D, crocodile[i]))
        {
            graph[i].push_back(N + 1);
            graph[N + 1].push_back(i);
        }
        for (int j = i + 1; j < N; j++)
        {
            if (DistanceOfPoints(crocodile[i], crocodile[j]) <= D)
            {
                graph[i].push_back(j);
                graph[j].push_back(i);
            }
        }
    }
    // 如果湖心小岛和岸边距离小于D
    if (50 - 7.5 <= D)
    {
        graph[N].push_back(N + 1);
        graph[N + 1].push_back(N);
        printf("1\n");
        return 0;
    }

    vector<vector<int> > path;

    vector<int> bestPath = UnweightedShortestWay(N, graph, crocodile);

    if (graph[N].empty() || graph[N + 1].empty())
    {
        printf("0\n");
        return 0;
    }
    int i = N + 1;
    int n = 0;
    stack<Coordinate> pathStack;
    while (bestPath[i] != -1)
    {
        i = bestPath[i];
        pathStack.push(crocodile[i]);
        n++;
    }

    printf("%d\n", pathStack.size() + 1);

    while (!pathStack.empty())
    {
        printf("%d %d\n", pathStack.top().x, pathStack.top().y);
        pathStack.pop();
    }
    return 0;
}


06-图4. Saving James Bond - Hard Version (30)

标签:pat

原文地址:http://blog.csdn.net/qq_19672579/article/details/46509343

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!