B - 娜娜梦游仙境系列——跳远女王
Problem Description
娜娜觉得钢琴很无趣了,就抛弃了钢琴,继续往前走,前面是一片湖,娜娜想到湖的对岸,可惜娜娜找了好久都没找到小桥和小船,娜娜也发现自己不是神仙,不能像八仙过海一样。正当娜娜发愁的时候,娜娜发现湖上面有一些石头!娜娜灵机一动,发现可以沿着石头跳吖跳吖,这样一直跳下去,或许能跳到对岸!
娜娜把所有石头的位置都告诉你,然后娜娜能跳的最远距离也是知道的~请聪明的你告诉娜娜,她能够顺利到达对岸吗?
为了能够顺利的表达每个石头的位置,假设娜娜正在x轴上,表示湖的一岸,湖的另一岸是直线y=y0,湖中的石头都以有序二元组<x,y>表示,我们可以假设湖是无穷宽,两个石头的距离为几何距离,石头与岸的距离为点到直线的距离。
Input
多组数据,首先是一个正整数t(t<=20)表示数据组数
对于每组数据首先是三个整数y0(1<=y0<=1000),n(0<=n<=1000),d(0<=d<=1000),分别表示湖的另一岸的位置、石头的个数、娜娜一次最远能跳的距离。
接下来是n行,每行是两个整数x,y(0<=|x|<=1000,0<y<y0)
Output
对于每组数据,如果娜娜能够到达湖的另一岸,先输出“YES”,再输出一个整数,表示娜娜最少要跳多少次才能到达另一岸,
如果娜娜不能到达湖的另一岸,先输出“NO”,再输出一个整数,表示娜娜距离湖的另一岸最近的距离。(注意大小写)
Sample Input
2 4 3 1 0 1 0 2 0 3 6 3 2 0 1 1 2 2 3
Sample Output
YES 4 NO 3
Hint
样例一,从x轴->(0,1)->(0,2)->(0,3)->对岸,总共跳4步,输出4
样例二,从x轴->(0,1)->(1,2)->(2,3),此时距离对岸的距离为3,最大跳跃距离为2,无法到达对岸,故输出3;
题意:过河问题,起点为X轴上,输入三个数,y0,N,D,分别为Y=y0终点坐标,N为石头的数量,D为每一步所能够走的最大距离,给你N个石头的坐标,问你能否通过这些石头走到河对岸,如果可以的话,就输出所需要走的最短步数,否则输出距离河岸的最近距离;题目在于能够找到一条最短的路径,同时记录能够走得到的最远的Y坐标的距离。寻找最短路径就是用广搜,层层遍历,记录层数,用队列来保存能够到达的点,需要特色处理(把x轴看做一个点)下即可。
1 #include <iostream> 2 #include <stdio.h> 3 #include <math.h> 4 #include<stdio.h> 5 #include<string.h> 6 #include <stdlib.h> 7 #include <utility> 8 #include <map> 9 #include <queue> 10 #define MAX(x,y) ((x)>(y)?(x):(y)) 11 #define MIN(x,y) ((x)<(y)?(x):(y)) 12 #define SET(ID) memset(ID,0,sizeof(ID)) 13 using namespace std; 14 typedef struct Point 15 { 16 int X; 17 int Y; 18 int sign; /*标记当前这个数是否被用过*/ 19 }xy; 20 xy X_Y[10086]; /*点的个数*/ 21 int Len; /*Len每一步所能走的在最大值*/ 22 int End_Y; /*End_Y河对岸的坐标*/ 23 int N; /*N为石头的数量*/ 24 int SIGN; /*SIGN记录是否能够到达河对岸*/ 25 double Distance(xy p1,xy p2) /*距离公式*/ 26 { 27 double x=p2.X-p1.X,y=p2.Y-p1.Y; 28 return sqrt(x*x+y*y); 29 } 30 int BFS() 31 { 32 queue<int> q;/*队列中保存的指是对应点的下标*/ 33 int Times=0; /*Times记录当前这个点在队列中的位置*/ 34 int times=1; /*times记录队尾的位置*/ 35 int Max_Y=X_Y[0].Y=0; 36 int Step[10086]; /*记录当前为第几层搜索*/ 37 SET(Step); /*初始化*/ 38 q.push(0); /*先把X轴进队列*/ 39 X_Y[0].sign=1; /*标记X轴使用过*/ 40 Step[Times]=0; /*记录当前搜索层数为0*/ 41 while(!q.empty()) /*队列不为空,则继续操作*/ 42 { 43 int Now=q.front();/*获取队头元素,作为当前的点*/ 44 q.pop();/*出队头元素*/ 45 if(X_Y[Now].Y+Len>=End_Y){SIGN=1;return 1;} /*如果第一步就能够*/ 46 Max_Y=MAX(Max_Y,X_Y[Now].Y); /*记录能够走得到的最远的Y坐标的距离*/ 47 for(int j=1;j<=N;j++) /*点的个数从一开始记数,X_Y[0]是作为x轴*/ 48 { 49 if(X_Y[j].sign==1)continue; /*判断这个点是否进队列,已经进队列则不在判断*/ 50 if(Now==0) /*当这点为X轴时,特殊处理,设定坐标为(x,0)*/ 51 {X_Y[Now].X=X_Y[j].X;} 52 double Jude_Len=Distance(X_Y[Now],X_Y[j]);/*求距离*/ 53 if(Jude_Len<=Len) /*两点距离是否小于能够走的最大距离*/ 54 { 55 q.push(j); 56 Step[times++]=Step[Times]+1; /*符合条件的点的层数=当前搜索层数+1*/ 57 if(X_Y[j].Y>=End_Y) /*如果当前的位置超过终点*/ 58 {SIGN=1;return Step[times-1];} 59 if(X_Y[j].Y+Len>=End_Y) /*如果当前的位置再加上一步能够超过终点*/ 60 {SIGN=1;return (Step[times-1]+1);} 61 X_Y[j].sign=1; /*标记这个点是否已经进队列*/ 62 } 63 } 64 Times++; 65 } 66 if(!SIGN) 67 return Max_Y; 68 69 70 } 71 int main() 72 { 73 int T,X,Y,Run_Len; 74 int Min_Step; 75 xy Now_XY; 76 double Jude_Len; 77 scanf("%d",&T); 78 while(T--) 79 { 80 scanf("%d%d%d",&End_Y,&N,&Len); 81 { 82 SIGN=0; X_Y[0].sign=0; 83 for(int i=1;i<=N;i++) 84 { 85 scanf("%d%d",&X_Y[i].X,&X_Y[i].Y); 86 X_Y[i].sign=0; /*初始化标记为0*/ 87 } 88 Min_Step=BFS(); 89 if(SIGN) 90 printf("YES\n%d\n",Min_Step); 91 else 92 printf("NO\n%d\n",End_Y-Min_Step); 93 } 94 } 95 return 0; 96 } 97 98 /* 99 2 100 10 10 2 101 1 4 102 2 3 103 2 2 104 1 6 105 8 5 106 7 6 107 1 8 108 9 2 109 7 9 110 5 4 111 112 */
转载请附上博客原文:http://www.cnblogs.com/LWF5201314614/p/4424634.html。