数据结构-Saving James Bond - Easy Version(创建图和图遍历)

题目

This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured by a group of drug dealers. He was sent to a small piece of land at the center of a lake filled with crocodiles. There he performed the most daring action to escape -- he jumped onto the head of the nearest crocodile! Before the animal realized what was happening, James jumped again onto the next big head... Finally he reached the bank before the last crocodile could bite him (actually the stunt man was caught by the big mouth and barely escaped with his extra thick boot).

Assume that the lake is a 100 by 100 square one. Assume that the center of the lake is at (0,0) and the northeast corner at (50,50). The central island is a disk centered at (0,0) with the diameter of 15. A number of crocodiles are in the lake at various positions. Given the coordinates of each crocodile and the distance that James could jump, you must tell him whether or not he can escape.

Input Specification:

Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of crocodiles, and D, the maximum distance that James could jump. Then N lines follow, each containing the (x,y) location of a crocodile. Note that no two crocodiles are staying at the same position.

Output Specification:

For each test case, print in a line "Yes" if James can escape, or "No" if not.

Sample Input 1:

14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12

Sample Output 1:

Yes

Sample Input 2:

4 13
-12 12
12 12
-12 -12
12 -12

Sample Output 2:

No

运行结果

Case Hint Result Run Time Memory
0 sample 有不成功的分支,连续几次到岸;有可以到岸但跳不过去的,多连通 Accepted 2 ms 540 KB
1 sample 都可以跳到,但不到岸 Accepted 2 ms 444 KB
2 最小N Accepted 3 ms 384 KB
3 最小跳,人工乱序 Accepted 2 ms 384 KB
4 最大N最小跳,4象限对称,人工乱序 Accepted 2 ms 360 KB
5 都能到岸,但够不着 Accepted 2 ms 364 KB

程序



#include<iostream>
#include<math.h>
using namespace std;

#define MaxVertexNum 101 //最多顶点数:最多鲨鱼数100+湖中心点1

typedef int Vertex; //用顶点下标表示顶点
typedef int WeightType; //边的权重-两点的距离

//边的定义
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2; //有向边<V1,V2>
    WeightType Weight; //权重
};
typedef PtrToENode Edge;

//邻接点的定义
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
    Vertex AdjV; //邻接点的下标
    WeightType Weight; //边权重
    PtrToAdjVNode Next; //指向下一个邻接点的指针
};

//顶点表头结点的定义
typedef struct Vnode{
    PtrToAdjVNode FirstEdge; //变表头指针
} AdjList[MaxVertexNum]; //AdjList是邻接表类型

//图结点的定义
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv; //顶点数
    int Ne; //边数
    int *X; //顶点的横坐标数组指针
    int *Y; //顶点的竖坐标数组指针
    int D; //007能跨越的最大距离
    bool *visited; //顶点被访问状态数组的指针
    bool Arrival; //表示007是否可以跳到岸边
    AdjList G; //邻接表
};
typedef PtrToGNode LGraph; //以邻接表方式存储的图类型

LGraph CreateGraph(int Nv, int *X, int *Y, int D);
void InsertEdge(LGraph Graph, Edge E);
void DFS0ListComponents(LGraph Graph);
void DFS(LGraph Graph, Vertex v);
bool ArrivalState(LGraph Graph, Vertex v);

int main()
{
    /*测试用例
    int N, D;
    N = 14; //鲨鱼总数
    D = 20; //007能跨越的最大距离
    int RADIUS = 8;//中心点圆盘的半径
    int Nv = N+1;//顶点总数=鲨鱼总数+一个湖中心点
    int VD; //两点的欧式距离

    int X[Nv] = {0,25,-25,8,29,-35,5,27,-8,-20,-25,-13,-30,-35,12};
    int Y[Nv] = {0,-15,28,49,15,-2,28,-29,-28,-35,-20,29,15,40,12};
    //Nv = 5;
    //D = 13;
    //int X[Nv] = {-12,12,-12,12};
    //int Y[Nv] = {12,12,-12,-12};

    LGraph Graph;
    Graph = CreateGraph(Nv, X, Y, D);

    Edge E;
    E = new ENode;

    int i=0; int j=1;
    for(i=0; i<Nv-1; i++){
        for(j=i+1; j<Nv; j++){
            VD = sqrt(pow(X[i] - X[j], 2) + pow(Y[i] - Y[j], 2));
            if(i == 0){
                VD = VD - RADIUS;
            }
            if(VD <= D){
                //表明<Vi,Vj>有边
                E->V1 = i;
                E->V2 = j;
                E->Weight = VD;
                InsertEdge(Graph, E);
            }
        }
    }


    DFS0ListComponents(Graph);
    */

    //正式应用
    int N, D, Nv, VD;
    int i, j;
    int RADIUS = 8;//中心点圆盘的半径
    LGraph Graph;
    Edge E;

    cin >> N; //鲨鱼总数
    cin >> D; //007能跨越的最大距离
    Nv = N+1;//顶点总数=鲨鱼总数+一个湖中心点
    int X[Nv]; //存放鳄鱼坐标的横坐标
    int Y[Nv]; //存放鳄鱼坐标的纵坐标

    //输入鳄鱼的坐标
    for(int i=1; i<Nv; i++){
        cin >> X[i];
        cin >> Y[i];
    }
    X[0] = 0;
    Y[0] = 0;

    Graph = CreateGraph(Nv, X, Y, D);//创建无边图

    E = new ENode;

    //坐标之间长度不大于007的最大跳跃距离,则两顶点间有边
    i=0; j=1;
    for(i=0; i<Nv-1; i++){
        for(j=i+1; j<Nv; j++){
            VD = sqrt(pow(X[i] - X[j], 2) + pow(Y[i] - Y[j], 2));
            if(i == 0){
                VD = VD - RADIUS; //中心点到其他坐标点,应减去其圆盘半径
            }
            if(VD <= D){
                //表明<Vi,Vj>有边
                E->V1 = i;
                E->V2 = j;
                E->Weight = VD;
                InsertEdge(Graph, E);
            }
        }
    }

    //DFS仅遍历从顶点0开始连通的路径
    DFS0ListComponents(Graph);

    return 0;
}

bool ArrivalState(LGraph Graph, Vertex v)
{
    //判断顶点是否能够到西岸或东岸
    if( abs(Graph->X[v] + 50) <= Graph->D || (abs(Graph->X[v] - 50) <= Graph->D))
        return true;
    //判断顶点是否能够到北岸或南岸
    else if( abs(Graph->Y[v] - 50) <= Graph->D || (abs(Graph->Y[v] + 50) <= Graph->D))
        return true;
    else
        return false;
}

void DFS0ListComponents(LGraph Graph)
{
    bool Arrival;
    if(Graph->Nv != 0){/*图中有结点*/
        //cout << "{ ";
        DFS(Graph, 0);
        //cout << "}\n";
    }
    if(Graph->Arrival)
        cout << "Yes" <<endl;
    else
        cout << "No" <<endl;
}

void DFS(LGraph Graph, Vertex v)
{
    PtrToAdjVNode W;

    Graph->visited[v] = true;
    //cout << v << " ";

    if(Graph->Arrival) return;

    Graph->Arrival = ArrivalState(Graph, v);
    //cout << "Arrival: " << Graph->Arrival << " ";

    for(W = Graph->G[v].FirstEdge; (W && !Graph->Arrival); W=W->Next){
        if(!Graph->visited[W->AdjV])
            DFS(Graph, W->AdjV);
    }
}

void InsertEdge(LGraph Graph, Edge E)
{
    PtrToAdjVNode NewNode;

    //插入边<V1,V2>
    //为V2建立新的邻接点
    NewNode = new AdjVNode;
    NewNode->AdjV = E->V2;
    NewNode->Weight = E->Weight;

    //将V2插入V1表头
    NewNode->Next = Graph->G[E->V1].FirstEdge;
    Graph->G[E->V1].FirstEdge = NewNode;

    //此为无向图,还要插入<V2,V1>
    //为V1建立新的邻接点
    NewNode = new AdjVNode;
    NewNode->AdjV = E->V1;
    NewNode->Weight = E->Weight;

    //将V1插入V1表头
    NewNode->Next = Graph->G[E->V2].FirstEdge;
    Graph->G[E->V2].FirstEdge = NewNode;
}

LGraph CreateGraph(int Nv, int *X, int *Y, int D)
{
    LGraph Graph;
    Vertex v;

    Graph = new GNode;
    Graph->Nv = Nv;
    Graph->Ne = 0;
    Graph->X = X;
    Graph->Y = Y;
    Graph->D = D;
    Graph->Arrival;

    for(v=0; v<Graph->Nv; v++)
        Graph->G[v].FirstEdge = NULL;

    Graph->visited = new bool [Nv];
    for(int i=0; i<Nv; i++) Graph->visited[i] = false;

    return Graph;
}

猜你喜欢

转载自blog.csdn.net/Brianone/article/details/89495333