进阶实验6-3.4 拯救007(升级版) (30分)-BFS

解题思路:

1、先按第一跳距离升序

2、合法第一跳加入队列中

3、(广度优先)访问队列中的结点,每访问一个结点并将其可到达的子孙加入队列中,直至访问至某个结点可以到岸结束

#include <stdio.h>
#include <string.h>
#include <math.h>
#define MaxV 100+5
#define INF 0x3f3f3f3f
typedef struct {
    int x,y;
    double firstjump;
} GNode;
GNode G[MaxV];
int Q[MaxV],path[MaxV],dist[MaxV];
int n,D;
int Jump(int i,int j) {//从一个鳄鱼跳到另一个鳄鱼
    if(pow(G[i].x-G[j].x,2)+pow(G[i].y-G[j].y,2)<=pow(D,2))
        return 1;
    return 0;
}
int IsSafe(int i) {//是否可以直接上岸
    if(G[i].x-D<=-50||G[i].x+D>=50)
        return 1;
    if(G[i].y-D<=-50||G[i].y+D>=50)
        return 1;
    return 0;
}
void BFS() {//广度优先
    int u,v,w;
    int front=0,rear=0;
    for(v=0; v<n; v++) {
        if(G[v].firstjump>pow(7.5,2)&&G[v].firstjump<=pow(D+7.5,2)) {//合法第一跳加入队列
            Q[rear++]=v;
            dist[v]=1;
            path[v]=-1;
        }
    }
    while(front<rear) {
        u=Q[front++];//依次访问队列中的结点
        if(IsSafe(u)&&dist[n]==INF) {//如果可以直接上岸,结束
            dist[n]=dist[u]+1;
            path[n]=u;
            break;
        }
        for(w=0; w<n; w++) {
            if(dist[w]==INF&&Jump(u,w)) {//u结点可到达w结点,则w入队
                Q[rear++]=w;
                dist[w]=dist[u]+1;
                path[w]=u;
            }
        }
    }
}
int cmp(GNode a,GNode b) {
    return a.firstjump-b.firstjump;
}
int main() {
    scanf("%d %d",&n,&D);
    int i;
    for(i=0; i<n; i++) {
        scanf("%d %d",&G[i].x,&G[i].y);
        G[i].firstjump=pow(G[i].x,2)+pow(G[i].y,2);
    }
    if(D>=42.5) {
        printf("1\n");
        return 0;
    }
    qsort(G,n,sizeof(G[0]),cmp);//第一跳距离升序
    memset(dist,INF,sizeof(dist));
    memset(path,-1,sizeof(path));
    BFS();
    if(dist[n]==INF) {
        printf("0\n");
        return 0;
    }
    printf("%d\n",dist[n]);
    int u=path[n];
    int tmp[n];
    memset(tmp,-1,sizeof(tmp));
    int k=0;
    while(u!=-1) {
        tmp[k++]=u;
        u=path[u];
    }
    for(i=k-1; i>=0; i--) {//倒序输出路径
        printf("%d %d\n",G[tmp[i]].x,G[tmp[i]].y);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/snzhong/p/12636104.html

时间: 2024-10-03 22:29:19

进阶实验6-3.4 拯救007(升级版) (30分)-BFS的相关文章

进阶实验8-2.1 逆散列问题 (30分)

给定长度为 N 的散列表,处理整数最常用的散列映射是 (.如果我们决定用线性探测解决冲突问题,则给定一个顺序输入的整数序列后,我们可以很容易得到这些整数在散列表中的分布.例如我们将 1.2.3 顺序插入长度为 3 的散列表HT[]后,将得到HT[0]=3,HT[1]=1,HT[2]=2的结果. 但是现在要求解决的是“逆散列问题”,即给定整数在散列表中的分布,问这些整数是按什么顺序插入的? 输入格式: 输入的第一行是正整数 N(≤1000),为散列表的长度.第二行给出了 N 个整数,其间用空格分隔

数据结构--图(上)--应用实例:拯救007+六度空间

应用实例:拯救007 总体算法 应用实例:六度空间

图的基本概念,图的遍历、拯救007

图(graph):表示"多对多"的关系六度空间理论(Six Degrees Separation)包含:1.一组顶点:通常用V(Vertex)表示顶点集合2.一组边:通常用E(edge)表示边的集合 边是顶点对:(v, w) 属于E, v , w 属于V 有向边<v, w>表示v 指向w的边(单行线) 不考虑重边和自回路 抽象数据类型定义:1.类型名称:图2.数据对象集:G(V, E)由一个非空的有限顶点集合v 和一个有限边集合Ezucheng 2.操作集: 常见术语:有向

00拯救007

这道题看起来好像还是挺难的,毕竟文字就已经挺多的了.但我现在做出来了,我也可以假装一波了:其实吧,这道题也不是很难.认真想一想也还是可以做出来的.(那个在图书馆搞了3个钟的人不是我)哈哈. 好了,言归正传,我们一起来看看这道题吧.为了让下面的分析比较清晰明了,这里我先放张题目的图片吧. 前面的情节带入都不关键的东西知道是要拯救007就可以了,后面的以坐标式的输入则让我找到了存储的结构.很明显,找到跳脱的路线,不也是可以理解为在地图里面找到正确的路线吗.再加上我们这一章我们学的就是图.基本数据结构

进阶实验6-3.6 最小生成树的唯一性 (35分)

给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一.本题就要求你计算最小生成树的总权重,并且判断其是否唯一. 输入格式: 首先第一行给出两个整数:无向图中顶点数 N(≤)和边数 M.随后 M 行,每行给出一条边的两个端点和权重,格式为“顶点1 顶点2 权重”,其中顶点从 1 到N 编号,权重为正整数.题目保证最小生成树的总权重不会超过 2?30??. 输出格式: 如果存在最小生成树,首先在第一行输出其总权重,第二行输出“Yes”,如果此树唯一,否则输出“No”.如

进阶实验2-3.1 海盗分赃 (25分)

P 个海盗偷了 D 颗钻石后来到公海分赃,一致同意如下分赃策略: 首先,P 个海盗通过抽签决定 1 - P 的序号.然后由第 1 号海盗提出一个分配方案(方案应给出每个海盗分得的具体数量),如果能够得到包括 1 号在内的绝对多数(即大于半数)同意,则按照该分配方案执行,否则 1 号将被投入大海喂鲨鱼:而后依次类似地由第 2 号.第 3 号等等海盗提出方案,直到能够获得绝对多数同意的方案出现为止,或者只剩下最后一位海盗,其独占所有钻石.请编写一个程序,给出第 1 号海盗的钻石分配方案中自己分得的钻

进阶实验6-3.2 社交网络图中结点的“重要性”计算 (30分)-dijkstra算法

解题思路:(邻接矩阵存储) 用dijkstra算法依次求出每个结点到其余结点的最短距离 #include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MaxVex 1000+10 int G[MaxVex][MaxVex]; int visit[MaxVex]; int Nv,Ne; void Init() { memset(G,INF,sizeof(G)); int i; for(i=1; i<=

进阶实验6-3.3 天梯地图 (30分)-Dijkstra

解题思路:采用Dijkstra算法,算两次,一次算最短时间,一次算最短路径,另开一数组记录路径 #include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MaxVex 500 typedef struct { int length; int time; } Graph; Graph G[MaxVex][MaxVex];//图 int visit[MaxVex]= {0};//访问标记 int fpat

进阶实验8-2.3 二叉搜索树的最近公共祖先 (30分)

解题思路: 1.定义一个结构体,来存储二叉排序树 typedef struct { int data; int left; int right; int parent; int h; } T; 2.再定义一个结构体,将输入数据存入 typedef struct { int data; int pos; } Info; 3.对输入数据排序 4.用二分法确实查询数据是否存在树中 5.寻找最近公共祖先 1)如果x,y均不是根结点 1.1.如果x==y,则x是y的祖先 1.2.若x,y分别在左右子树,则