B - 娜娜梦游仙境系列——跳远女王
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
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
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <list> 13 #include <iomanip> 14 #include <cstdlib> 15 #include <sstream> 16 using namespace std; 17 typedef long long LL; 18 const int INF=0x5fffffff; 19 const double EXP=1e-6; 20 const int MS=1005; 21 22 int des,n,maxv; 23 24 25 double edges[MS][MS]; 26 int cnt[MS]; 27 bool flag[MS]; 28 29 30 struct point 31 { 32 int x,y; 33 }points[MS]; 34 35 double distence(point &a,point &b) 36 { 37 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 38 } 39 40 int main() 41 { 42 int T; 43 scanf("%d",&T); 44 while(T--) 45 { 46 scanf("%d%d%d",&des,&n,&maxv); 47 int x,y; 48 for(int i=1;i<=n;i++) 49 { 50 scanf("%d%d",&x,&y); 51 points[i].x=x; 52 points[i].y=y; 53 } 54 55 for(int i=1;i<=n;i++) 56 cnt[i]=INF; 57 58 memset(flag,false,sizeof(flag)); 59 60 queue<int > que; 61 62 for(int i=1;i<=n;i++) 63 { 64 if(points[i].y<=maxv) 65 { 66 cnt[i]=1; 67 que.push(i); 68 } 69 if(des-points[i].y<=maxv) 70 flag[i]=true; 71 for(int j=i+1;j<=n;j++) 72 { 73 edges[i][j]=edges[j][i]=distence(points[i],points[j]); 74 } 75 } 76 while(!que.empty()) 77 { 78 int u=que.front(); 79 que.pop(); 80 for(int v=1;v<=n;v++) 81 { 82 if((u!=v)&&edges[u][v]<=(double)(maxv+EXP)) 83 { 84 if(cnt[u]+1<cnt[v]) 85 { 86 cnt[v]=cnt[u]+1; 87 que.push(v); 88 } 89 } 90 } 91 92 } 93 94 if(des<=maxv) 95 { 96 printf("YES 1 "); 97 continue; 98 } 99 100 if(n==0) 101 { 102 if(des<=maxv) 103 printf("YES 1 "); 104 else 105 printf("NO %d ",des); 106 continue; 107 } 108 109 int ans=INF; 110 int t=0; 111 for(int i=1;i<=n;i++) 112 { 113 if(flag[i]) 114 { 115 if(cnt[i]<INF) 116 { 117 if(ans>cnt[i]+1) 118 ans=cnt[i]+1; 119 } 120 } 121 if(cnt[i]<INF) 122 { 123 if(points[i].y>t) 124 t=points[i].y; 125 } 126 } 127 128 if(ans<INF) 129 { 130 printf("YES "); 131 printf("%d ",ans); 132 } 133 else 134 { 135 printf("NO "); 136 printf("%d ",des-t); 137 } 138 } 139 return 0; 140 }