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
这题一句话不会做,参考月神代码,自己整理了一遍思路,自己敲了一下,
主要就是使用vector容器进行邻接表的储存和使用queue容器进行广搜bfs,
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
struct point
{
int x,y;
}p[1005];
vector <int> mp[1005];
struct answer
{
int num,step;
answer(){}
answer(int num,int step):num(num),step(step){}
};
int t,yo,n,d;
int ok;
bool dis(point a,point b)
{
if(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))<=d)
return 1;
return 0;
}
int vis[1005];
int bfs()
{
ok=0;
int mian=yo;
queue<answer> qu;
qu.push(answer(0,0));
while(!qu.empty())
{
answer tmp=qu.front();
qu.pop();
mian=min(mian,yo-p[tmp.num].y);
if(tmp.num==n+1)
{
ok=1;
return tmp.step;
}
for(int i=0;i<mp[tmp.num].size();i++)
{
if(!vis[mp[tmp.num][i]])
{
vis[mp[tmp.num][i]]=1;
qu.push(answer(mp[tmp.num][i],tmp.step+1));
}
}
}
return mian;
}
int main()
{
cin>>t;
while(t--)
{
for(int i=0;i<1005;i++)
mp[i].clear();
memset(vis,0,sizeof(vis));
cin>>yo>>n>>d;
for(int i=1;i<=n;i++)
cin>>p[i].x>>p[i].y;
if(yo<=d)
mp[0].push_back(n+1);
for(int i=1;i<=n;i++)
{
if(p[i].y<=d)
mp[0].push_back(i);
if(yo-p[i].y<=d)
mp[i].push_back(n+1);
for(int j=i+1;j<=n;j++)
if(dis(p[i],p[j]))
{
mp[i].push_back(j);
mp[j].push_back(i);
}
}
int tt=bfs();
if(ok)
cout<<"YES"<<endl<<tt<<endl;
else
cout<<"NO"<<endl<<tt<<endl;
}
}