04-树5 Root of AVL Tree (25分)
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted.
Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the root of the resulting AVL tree in one line.
Sample Input 1:
5
88 70 61 96 120
Sample Output 1:
70
Sample Input 2:
7
88 70 61 96 120 90 65
Sample Output 2:
88
#include<stdio.h> #include<malloc.h> #define EH 0 //等高 #define RH -1 //右高 #define LH 1 //左高 typedef struct BSTNode *BSTree; void L_Rotate(BSTree &p); void R_Rotate(BSTree &p); void LeftBalance(BSTree &T); void RightBalance(BSTree &T); int InsertAVL(BSTree &T, int e, bool &taller); struct BSTNode { int data; int bf; //-1代表右高,1代表左高,0代表左右一样高 BSTree lchild; BSTree rchild; }; int main() { int n; scanf_s("%d", &n); int x; BSTree T=NULL; bool taller = false; for (int i = 0; i < n; i++) { scanf_s("%d", &x); InsertAVL(T, x, taller); } printf("%d ", T->data); return 0; } //右旋 void R_Rotate(BSTree &p) { BSTree lc; lc = p->lchild; //lc指向p的左子树的根结点 p->lchild = lc->rchild; //p的左子树接lc的右子树 lc->rchild = p; //lc的右子树接p p = lc; //p指向新的根结点 } //左旋 void L_Rotate(BSTree &p) { BSTree rc = p->rchild; //rc指向p的右子树的根结点 p->rchild = rc->lchild; //p的右子树接rc的左子树 rc->lchild = p; //rc的左子树接为p p = rc; //p指向新的根结点 } int InsertAVL(BSTree &T, int e, bool &taller) { //若在平衡的二叉搜索树T中不存在和e相同的结点则插入一个新结点,返回1,否则返回0 //若因插入使二叉搜索树失去平衡,则做平衡旋转处理,bool类型判断T是否长高 if (!T){//插入新结点,树长高,taller置为True T = (BSTree)malloc(sizeof(BSTNode)); T->data = e; T->lchild = T->rchild = NULL; T->bf = EH; taller = true; } else { if (e == T->data) //存在和e相同的结点不插入 { taller = false; return 0; } if (e < T->data) //应在T的左子树中进行搜索 { if (!InsertAVL(T->lchild, e, taller)) //返回值为0说明左子树中存在相同的结点,则直接return 0; return 0; if (taller) //如果树长高了,判断是否需要平衡 { switch (T->bf) //检查T的平衡因子 { case LH: //原来左子树比右子数高,又插入在左子树中,需要做平衡 LeftBalance(T); taller = false; break; case EH: T->bf = LH; taller = true; break; case RH: T->bf = EH; taller = false; break; } } } else //在T的右子树种进行搜索 { if (!InsertAVL(T->rchild, e, taller)) //返回值为0,说明右子树种存在相同的结点,不用插入 return 0; if (taller) { switch (T->bf) { case LH: T->bf = EH; taller = false; break; case EH: T->bf = RH; taller = true; break; case RH: RightBalance(T); taller = false; break; } } } } return 1; } void LeftBalance(BSTree &T) { //对以T为根结点的二叉树做左平衡旋转,结束后,指针T指向新的根结点 BSTree lc = T->lchild; switch (lc->bf) //检查T的左子树的平衡因子 { case LH: //如果左边高,则做右旋操作 T->bf = lc->bf = EH; //先修改平衡因子,右旋后,平衡因子置为EH R_Rotate(T); break; case RH: //如果右高,新结点插在T的左子树的右子树上,应做左右双旋 BSTree rd = lc->rchild; switch (rd->bf) //按照三种情况修改,T和lc的平衡因子 { case LH:lc->bf = EH; T->bf = RH; break; case EH:lc->bf = T->bf = EH; break; case RH:T->bf = EH; lc->bf = LH; break; } rd->bf = EH; //修改rd的平衡因子 L_Rotate(T->lchild); //对T的左子树进行左旋,旋转之后T的左孩子变为rd; R_Rotate(T); //然后对T进行右旋操作 break; } } void RightBalance(BSTree &T) { BSTree rc = T->rchild; //rc指向T的右子树 switch (rc->bf) { case RH: //插入在T的右子树的右子树上,应进行右旋操作 T->bf = rc->bf = EH;//先修改T和T的右子树的平衡因子 L_Rotate(T); break; case LH: //插入在T的右子树的左子树上,应进行右左双选操作 BSTree ld = rc->lchild; switch (ld->bf) { case LH:T->bf = EH; rc->bf = RH; break; case EH:T->bf = rc->bf = EH; break; case RH:T->bf = LH; rc->bf = EH; break; } ld->bf = EH; R_Rotate(T->rchild); //对T的右子树进行右旋,旋转后T的右子树的根结点变成ld L_Rotate(T); //然后对T进行左旋 break; } }
/*分析:
完全二叉搜索树,满足二叉搜索树的性质也满足完全二叉树的性质,画图可以知道,右边的值都比左边的大
可以先排个序,每个根结点的值排的位置都是左子树的个数,加上他左边的结点的个数.
#include<stdio.h> #include<math.h> #include<stdlib.h> #define Maxsize 1000 typedef struct TNode *BSTree; int a[1000]; struct TNode { int data; BSTree left; BSTree right; }; //队列的顺序存储 struct QNode { BSTree *bst; int front, rear; int maxsize; }; typedef struct QNode *Queue; Queue CreateQueue() { Queue Q = (Queue)malloc(sizeof(struct QNode)); Q->bst = (BSTree *)malloc(Maxsize*sizeof(struct TNode)); Q->front = Q->rear = 0; Q->maxsize = Maxsize; return Q; } int IsEmpty(Queue Q) { if (Q->front == Q->rear) return 1; else return 0; } //选择排序 void sort(int a[], int n) { for (int i = 0; i<n; i++) { for (int j = i + 1; j<n; j++) { if (a[i]>a[j]) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } } } //求左子树结点的个数 int LeftNum(int n) { int k=0;// n个结点的树的层数 int m=1; //m-1表示k层满二叉树的结点个数 int p;//表示左子树结点的个数 while (m < n + 1) { m = 2 * m; k++; } if (m - 1 - (int)pow(2.0, k - 2) <= n) //左子树是满的 { p = (int)(pow(2.0, k - 1)) - 1; } else p = n - (int)pow(2.0, k - 2); return p; } BSTree Insert(int left, int n, BSTree T); void preOrderTravasel(BSTree T); void LevelTravasel(BSTree T); int main() { int n; scanf("%d", &n); for (int i = 0; i<n; i++) { scanf("%d", &a[i]); } //从小到大排序 sort(a, n); BSTree T=NULL; T=Insert(0, n,T); //preOrderTravasel(T); LevelTravasel(T); printf(" "); return 0; } void preOrderTravasel(BSTree T) { if (T != NULL) { printf("%d ", T->data); preOrderTravasel(T->left); preOrderTravasel(T->right); } } BSTree Insert(int left, int n, BSTree T) { if (n == 0) return NULL; T = (BSTree)malloc(sizeof(struct TNode)); int p = LeftNum(n); //左子树的个数 int m = n - p-1; //右子树的个数 T->data = a[p + left]; T->left = Insert(left, p, T->left); T->right = Insert(left + p + 1, m, T->right); return T; } void LevelTravasel(BSTree T) { Queue Q = CreateQueue(); Q->bst[Q->rear++] = T; int i = 0; while (IsEmpty(Q) == 0) { T = Q->bst[Q->front++]; if (i++ == 0) printf("%d", T->data); else printf(" %d", T->data); if (T->left != NULL) { Q->bst[Q->rear++] = T->left; } if (T->right != NULL) { Q->bst[Q->rear++] = T->right; } } }
Sample Input:
7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11
#include<stdio.h> #include<malloc.h> #include<string.h>
//分析:
//判断是否是最优解,其实就是判断wpl是否最小
//加上没有二义性,需要是前缀码
//算法思路:根据输入的,建立一个哈夫曼树,寻找两个最小的值,然后插入需要借助堆,然后求出最小的wpl.判断输入的每一组数据是否是前缀码和wpl最小
int value[256]; //哈夫曼树的定义 typedef struct TreeNode *HuffmanTree; typedef struct TreeNode { int weight; char data; HuffmanTree left, right; }Node; //最小堆 typedef struct TNode { HuffmanTree *data; int size; }*MinHeap; void Insert(int n, HuffmanTree T, MinHeap H); //最小堆插入 HuffmanTree Delete(MinHeap H); //最小堆删除 HuffmanTree BuildHuffman(MinHeap H); //建一个哈夫曼树 int Judge(int n, int totalspace); //判断是否是最右键 int WPL(HuffmanTree T, int Depth); //求wpl int main() { MinHeap H = (MinHeap)malloc(sizeof(struct TNode)); H->data = (HuffmanTree *)malloc(1001 * sizeof(HuffmanTree)); H->size = 0; //哨兵 HuffmanTree a = (HuffmanTree)malloc(sizeof(struct TreeNode)); a->weight = -1000; H->data[0] = a; int n; scanf_s("%d ", &n); //生成一个最小堆 for (int i = 0; i<n; i++) { Insert(1, NULL, H); } //建一个哈夫曼树 HuffmanTree T = BuildHuffman(H); //计算哈夫曼树形成的哈夫曼编码的最小wpl int Space = WPL(T,0); int m; scanf_s("%d", &m); getchar(); for (int i = 0; i<m; i++) { int sum; //输入的编码的wpl和最优的比较 sum=Judge(n,Space); if (sum == Space) printf("Yes "); else printf("No "); } } //最小堆的插入 void Insert(int n, HuffmanTree T, MinHeap H) { if (n == 1){ //当n=1时,是输入,建一个最小堆 char c; int weight; scanf_s("%c %d", &c, 1, &weight); int index = c; //将字母的权重存起来 value[index] = weight; getchar(); T = (Node *)malloc(sizeof(struct TreeNode)); T->weight = weight; T->data = c; T->left = NULL; T->right = NULL; int i = ++H->size; for (; H->data[i / 2]->weight>weight; i /= 2) { //向上过滤 H->data[i] = H->data[i / 2]; } //将T插入 H->data[i] = T; } else if (n == 2){ //n=2是插入一个结点 int i = ++H->size; for (; H->data[i / 2]->weight>T->weight; i /= 2){ H->data[i] = H->data[i / 2]; } H->data[i] = T; } } int WPL(HuffmanTree T, int Depth) { /* 整棵树的WPL */ if (!T->left && !T->left) { return Depth*T->weight; } else return WPL(T->left, Depth + 1) + WPL(T->right, Depth + 1); } //删除最小堆的堆顶元素 HuffmanTree Delete(MinHeap H) { HuffmanTree min = H->data[1]; //保存最后一个元素 int temp = H->size--; int child, parent; parent = 1; for (; parent * 2 <= H->size; parent = child) { //向下过滤,寻找要插入的位置 child = parent * 2; //找左右小的 if (child != H->size&&H->data[child + 1]->weight < H->data[child]->weight) { child++; } if (H->data[child]->weight >= H->data[temp]->weight) break; else { H->data[parent] = H->data[child]; } } //插入最后一个元素 H->data[parent] = H->data[temp]; return min; } //判断是否是最优解 int Judge(int n, int totalspace) { char c; char a[63]; char **str = (char **)malloc(n * 63 * sizeof(char)); for (int i = 0; i < n; i++) { //给n个字符串开辟空间 str[i] = (char *)malloc(63 * sizeof(char)); } int sum = 0; for (int i = 0; i < n; i++) { scanf_s("%c", &c, 1); getchar(); a[i] = c; scanf_s("%s", str[i], 63); getchar(); } //计算wpl for (int i = 0; i < n; i++) { sum += value[a[i]] * strlen(str[i]); } if (totalspace != sum) return -1; //字符串按长度排序 for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (strlen(str[i])>strlen(str[j])) { char *p = str[i]; str[i] = str[j]; str[j] = p; char t = a[i]; a[i] = a[j]; a[j] = t; } } } //判断是否是前缀码 for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int flag = 1; if (strlen(str[i]) == strlen(str[j])) { if (strcmp(str[i], str[j]) == 0) return -1; continue; } for (int k = 0; k < strlen(str[i]); k++) { if (str[i][k] != str[j][k]) { flag = 0; break; } } if (flag == 1) return -1; } } return sum; } //生成一个哈夫曼树 HuffmanTree BuildHuffman(MinHeap H) { int i; HuffmanTree T; int size = H->size; if (H->size == 1) { T = (HuffmanTree)malloc(sizeof(struct TreeNode)); T->weight = H->data[1]->weight; T->left = (HuffmanTree)malloc(sizeof(struct TreeNode)); T->left->weight = H->data[1]->weight; T->right = NULL; T->left->left = NULL; T->left->right = NULL; return T; } for (i = 1; i<size; i++) { //直到,堆中只有一个元素 T = (HuffmanTree)malloc(sizeof(struct TreeNode)); //取出两个最小的值 T->left = Delete(H); T->right = Delete(H); //加起来后,插进去 T->weight = T->left->weight + T->right->weight; Insert(2, T, H); } //取出堆顶元素 T = Delete(H); return T;
}
Sample Input 1:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
Sample Output 1:
no
no
yes
There are 2 components.
Sample Input 2:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S
Sample Output 2:
no
no
yes
yes
The network is connected.
#include<stdio.h> #include<malloc.h> #define MAXN 1000 /* 集合最大元素个数 */ typedef int ElementType; /* 默认元素可以用非负整数表示 */ typedef int SetName; /* 默认用根结点的下标作为集合名称 */ typedef ElementType SetType[MAXN]; /* 假设集合元素下标从0开始 */ void Union(SetType S, SetName Root1, SetName Root2) { //按秩归并 //把元素少的集合连在元素多的上,可以降低树的高度 if (S[Root2] > S[Root1]) { S[Root1] += S[Root2]; S[Root2] = Root1; } else if (S[Root1] > S[Root2]) { S[Root2] += S[Root1]; S[Root1] = Root2; } } SetName Find(SetType S, ElementType X) { /* 默认集合元素全部初始化为-1 */ if (S[X] < 0) /* 找到集合的根 */ return X; else return S[X] = Find(S, S[X]); /* 路径压缩 */ //也是吧每一个路径上的元素,都直接连上根结点上,这样树的高度就降低了 } void Initial(SetType S, int n); //将集合中的每一个结点的parent置为-1 void Input_connection(SetType S); void Check_connection(SetType S); void Check_network(SetType S, int n); int main() { SetType S; int n; char in; //初始化集合 scanf_s("%d",&n); Initial(S, n); do{ scanf_s("%c", &in); switch (in){ case 'I':Input_connection(S); break; case 'C':Check_connection(S); break; case 'S':Check_network(S, n); } } while (in!='S'); return 0; } void Initial(SetType S, int n) { for (int i = 0; i < n; i++) { S[i]=-1; } } void Input_connection(SetType S) { int u, v; int root1, root2; scanf_s("%d %d ", &u, &v); //输入两个元素,然后找到,这两个元素的各自的集合,进行合并 root1 = Find(S, u - 1); root2 = Find(S, v - 1); Union(S, root1, root2); } void Check_connection(SetType S) { //检查两个元素是否在同一个集合中 int u, v; int root1, root2; scanf_s("%d %d ", &u, &v); //查找两个元素的根,是否是同一个结点 root1 = Find(S, u - 1); root2 = Find(S, v - 1); if (root1 == root2) printf("yes "); else printf("no "); } void Check_network(SetType S, int n) { //判断所有元素是否在同一个集合上 //小于0的只有一个,即只有一个集合,小于0的多个就有多个集合 int i,counter = 0; for (i = 0; i < n; i++) { if (S[i] < 0) counter++; } if (counter == 1) printf("The network is connected. "); else printf("There are %d components. ", counter); }
#include<stdio.h> //最小堆 int MinH[1001]; //size表示当前的最后一个结点的位置 int size = 0; void Insert(int x); void LuJin(int index); int main() { MinH[0] = -10001; int n, m; scanf_s("%d %d", &n, &m); for (int i = 0; i < n; i++) { int x; scanf_s("%d", &x); Insert(x); } for (int i = 0; i < m; i++) { int index; scanf_s("%d", &index); LuJin(index); } } //插入 void Insert(int x) { //要插入最后一个元素的位置 int i = ++size; for (; MinH[i / 2] > x; i /= 2) { //一直向上找 MinH[i] = MinH[i / 2]; } //找到后插入 MinH[i] = x; } void LuJin(int index) { int root = index; for (; root != 0; root /= 2) { if (root == index) printf("%d", MinH[root]); else printf(" %d", MinH[root]); } printf(" "); }
#include<stdio.h> #include<malloc.h>
//采用邻接表来表示图
/*算法思路:
先通过邻接表建一个图,建图时,需主要,题目要求从小到大,
故,每个链表都需要升序来排,不能直接头插了
然后先深度优先遍历,不连通的话,还需要一个for循环,
保证每个结点都被访问过,类似树的先序遍历
然后是广度优先遍历,类似树的层次遍历,需要队列*/
typedef struct node *List; typedef struct node *Node; struct node{ int V;//在数组中的下标 int weight; Node next; }; typedef struct VNode *PtrVNode; typedef struct VNode{ List firstEdge; }AdjList[1000]; AdjList G; int Nv; int Ne; int Visited[1000]; void visit(int Vertex) { printf("%d ", Vertex); } //定义队列 typedef struct queue{ int data[1000]; int front; int rear; int maxsize; }*Queue; Queue CreateQueue() { Queue Q = (Queue)malloc(sizeof(struct queue)); Q->front = Q->rear = 0; Q->maxsize = 1000; return Q; } void addQ(Queue Q, int x) { Q->data[Q->rear++] = x; } int DeleteQ(Queue Q) { return Q->data[Q->front++]; } int IsEmpty(Queue Q) { if (Q->front == Q->rear) return 1; else return 0; } void DFS(int V); void BFS(int V); int main() { scanf_s("%d %d", &Nv, &Ne); //初始化0条边,Nv个结点的图 for (int i = 0; i < Nv; i++) { G[i].firstEdge = NULL; } //插入Ne条边 int v1, v2, weight = 1; Node p; for (int i = 0; i < Ne; i++) { scanf_s("%d %d", &v1, &v2, &weight); //将v2插入到v1的链表中 Node NewNode = (Node)malloc(sizeof(struct node)); NewNode->V = v2; NewNode->weight = weight; if (G[v1].firstEdge == NULL) { NewNode->next = G[v1].firstEdge; G[v1].firstEdge = NewNode; } else{ p = G[v1].firstEdge; //链表升序 //寻找要插入的位置 if (v2 < p->V) { NewNode->next = G[v1].firstEdge; G[v1].firstEdge = NewNode; } else{ while (p->next != NULL&&v2 > p->next->V) p = p->next; //插入 NewNode->next = p->next; p->next = NewNode; } } //无向图,还需将v1插入到v2中 NewNode = (Node)malloc(sizeof(struct node)); NewNode->V = v1; NewNode->weight = weight; if (G[v2].firstEdge == NULL) { NewNode->next = G[v2].firstEdge; G[v2].firstEdge = NewNode; } else{ p = G[v2].firstEdge; //链表升序 //寻找要插入的位置 if (v1 < p->V) { NewNode->next = G[v2].firstEdge; G[v2].firstEdge = NewNode; } else{ while (p->next != NULL&&v1 > p->next->V) p = p->next; //插入 NewNode->next = p->next; p->next = NewNode; } } } //使用DFS和BFS遍历 for (int v = 0; v < Nv; v++) { int i = 0; if (!Visited[v]) { printf("{ "); DFS(v); i++; } if (i != 0) printf("} "); }
//遍历完后,需要将visited[]重新置为0 for (int v = 0; v < Nv; v++) { Visited[v] = 0; } for (int v = 0; v < Nv; v++) { int i = 0; if (!Visited[v]) { printf("{ "); BFS(v); i++; } if (i != 0) printf("} "); } } void DFS(int V) {
//先访问 visit(V); Visited[V] = 1; for (Node v = G[V].firstEdge; v != NULL; v = v->next) { if (!Visited[v->V]) //如果没有被访问,就访问 DFS(v->V); } } void BFS(int V) { Queue Q = CreateQueue(); visit(V); Visited[V] = 1; addQ(Q, V); Node p; while (!IsEmpty(Q)) { int v = DeleteQ(Q); for (p = G[v].firstEdge; p != NULL; p = p->next) { if (Visited[p->V] != 1){ visit(p->V); Visited[p->V] = 1; addQ(Q, p->V); } } } }
#include<stdio.h> #include<malloc.h> #include<math.h>
//算法思路:
//用坐标表示鳄鱼的位置
//两点距离小于跳的距离就表示两点相连
//第一跳的距离要加上岛的半径
//存在图中,然后dfs遍历图
typedef struct Location { double x; double y; }location,Node[101]; int G[101][101]; int Ne; int Nv; //判断是否能上岸 int flag = 0; int visited[102]; double Distance2(location a); //计算与岸上的距离 double Distance(location a, location b); //计算两点距离 void DFS(int v); int main() { double jump; Node node; node[0].x = 0; node[0].y = 0; scanf_s("%d %lf", &Nv,&jump); double distance; double distance2; for (int i = 1; i <= Nv; i++) { scanf_s("%lf %lf", &node[i].x, &node[i].y); } int flag1 = 0; for (int i = 0; i < Nv + 1; i++) { distance = Distance(node[0], node[i]) - 15; if (distance <= jump) { G[0][i] = 1; flag1 = 1; } } if (flag1 != 1) { printf("No "); return 0; } //插入边 for (int i = 1; i < Nv+1; i++) { //先算该结点是否与岸上相连 distance2= Distance2(node[i]); if (G[i][Nv+1] != 1 && distance2 <= jump) { G[i][Nv+1] = 1; } for (int j = i + 1; j < Nv+1; j++) { distance = Distance(node[i], node[j]); if (distance <= jump&&G[i][j]!=1) { G[i][j] = 1; G[j][i] = 1; } } } //判断有没有结点能上岸, flag1 = 0; for (int i = 0; i < Nv + 1; i++) { if (G[i][Nv + 1] == 1) { flag1 = 1; break; } } //没有结点与岸相连 if (flag1 == 0) { printf("No "); return 0; } DFS(0); if (flag == 1) printf("Yes "); else printf("No "); } double Distance(location a,location b) { double distance; distance = sqrt(double(a.x - b.x)*(a.x - b.x) + double(a.y - b.y)*(a.y - b.y)); return distance; } double Distance2(location a) { double Xdistance; double Ydistance; if (a.x >= 0){ Xdistance = 50 - a.x; } else Xdistance = a.x + 50; if (a.y >= 0){ Ydistance = 50 - a.y; } else Ydistance = a.y + 50; return Xdistance < Ydistance ? Xdistance : Ydistance; } void DFS(int v) { //判断是否与岸相连 visited[v]=1; if (v == Nv + 1) { flag = 1; return; } else { for (int i = 0; i < Nv + 2; i++) { if (G[v][i] == 1&&visited[i]!=1) { DFS(i); } } } }
Sample Input 1:
17 15
10 -21
10 21
-40 10
30 -50
20 40
35 10
0 -10
-25 22
40 -40
-30 30
-10 22
0 11
25 21
25 10
10 10
10 35
-30 10
Sample Output 1:
4
0 11
10 21
10 35
Sample Input 2:
4 13
-12 12
12 12
-12 -12
12 -12
Sample Output 2:
0
#include<cstdio> #include<stdlib.h> #include<iostream> using namespace std; typedef struct Node *List; struct Node { int v;//在图中的数组下标 List next; double distance; }; typedef struct GNode { List FirstEdge; double x; double y; double distance; }GNode,Graph[102]; double Distance2(GNode a); //计算与岸上的距离 double Distance1(GNode a,GNode b); //计算两点距离 void BFS(int S,int n); int dist[102] = {0};//存储距离 int path[102] = { 0 }; //存储路径 int a[100] = { 0 }; Graph G; typedef struct position { double x; double y; }Position[100]; int main01() { int n, distance; cin >> n; cin >> distance; //原点和岸边 G[0].FirstEdge = NULL; G[0].x = 0; G[0].y = 0; G[n + 1].FirstEdge = NULL; dist[0] = 0; dist[n + 1] = -1; path[n + 1] = -1; //初始化图,输入坐标 for (int i = 1; i <= n; i++) { cin >> G[i].x >> G[i].y; G[i].FirstEdge = NULL; dist[i] =path[i]= -1; } int j = 0; //如果第一跳直接跳上岸 if (Distance2(G[0]) <= distance + 7.5) { cout << 1 << endl; return 0; } //先判断有没有第一跳 for (int i = 1; i <= n; i++) { if (Distance1(G[0], G[i]) <= distance + 7.5) { List NewNode = (List)malloc(sizeof(struct Node)); NewNode->v = i; NewNode->next = G[0].FirstEdge; G[i].distance = Distance1(G[0], G[i]); NewNode->distance = Distance1(G[0], G[i]); G[0].FirstEdge = NewNode; j++; } } if (j == 0) { cout << 0 << endl; return 0; } //将第一跳按距离排序从小到大 for (List p = G[0].FirstEdge; p != NULL; p = p->next) { for (List p1 = p->next; p1 != NULL; p1 = p1->next) { if (p->distance > p1->distance) { int t = p->v; p->v = p1->v; p1->v = t; double tmp = p->distance; p->distance = p1->distance; p1->distance = tmp; } } } //插入边 int k = 0; for (int i = 1; i <= n; i++) { if (Distance2(G[i]) <= distance) { List NewNode = (List)malloc(sizeof(struct Node)); NewNode->v = n+1; NewNode->next = G[i].FirstEdge; G[i].FirstEdge = NewNode; k++; } for (int j = i + 1; j <= n; j++) { if (Distance1(G[i], G[j]) <= distance) { List NewNode = (List)malloc(sizeof(struct Node)); NewNode->v = j; NewNode->next = G[i].FirstEdge; G[i].FirstEdge = NewNode; NewNode = (List)malloc(sizeof(struct Node)); NewNode->v = i; NewNode->next = G[j].FirstEdge; G[j].FirstEdge = NewNode; } } } //如果没有与岸相连的结点 if (k == 0) { cout << 0 << endl; return 0; } //遍历 BFS(0, n); int p = path[n + 1]; int f = 1; Position array; //逆转path输出路径 while (p != 0) { array[f - 1].x = G[p].x; array[f - 1].y = G[p].y; f++; p = path[p]; } cout << f << endl; for (int j = f - 2; j >= 0; j--) { cout << array[j].x << " " << array[j].y << endl; } return 0; } double Distance1(GNode a, GNode b) { double distance; distance = sqrt((double)(a.x - b.x)*(a.x - b.x) + (double)(a.y - b.y)*(a.y - b.y)); return distance; } double Distance2(GNode a) { double Xdistance; double Ydistance; if (a.x >= 0){ Xdistance = 50 - a.x; } else Xdistance = a.x + 50; if (a.y >= 0){ Ydistance = 50 - a.y; } else Ydistance = a.y + 50; return Xdistance < Ydistance ? Xdistance : Ydistance; } typedef struct Queue { int data[102]; int front; int rear; }Queue; void BFS(int S,int n) { Queue Q; int v; Q.front = Q.rear = 0; Q.data[Q.rear++] = S; while (Q.front != Q.rear) { v = Q.data[Q.front++]; for (List p = G[v].FirstEdge; p != NULL; p = p->next) { if (dist[p->v] == -1) { if (p->v == n + 1) { dist[p->v] = dist[v] + 1; path[p->v] = v; return; } else { dist[p->v] = dist[v] + 1; path[p->v] = v; Q.data[Q.rear++] = p->v; } } } } }