在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑袋跳上岸去!(据说当年替身演员被最后一条鳄鱼咬住了脚,幸好穿的是特别加厚的靴子才逃过一劫。)
设鳄鱼池是长宽为100米的方形,中心坐标为 (0, 0),且东北角坐标为 (50, 50)。池心岛是以 (0, 0) 为圆心、直径15米的圆。给定池中分布的鳄鱼的坐标、以及007一次能跳跃的最大距离,你需要告诉他是否有可能逃出生天。
输入格式:
首先第一行给出两个正整数:鳄鱼数量 N(≤100)和007一次能跳跃的最大距离 D。随后 N 行,每行给出一条鳄鱼的 (x,y) 坐标。注意:不会有两条鳄鱼待在同一个点上。
输出格式:
如果007有可能逃脱,就在一行中输出"Yes",否则输出"No"。
输入样例 1:
14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12
输出样例 1:
Yes
输入样例 2:
4 13
-12 12
12 12
-12 -12
12 -12
输出样例 2:
No
作者
陈越
单位
浙江大学
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
题意如图 :
把所有靠近岛屿的点为起点dfs
即可,当dfs
到某个点point[i]
,能跳出去的条件是
x+D>=50 || x-D<=-50 || y+D>=50 || y-D<=-50
,即越出边界
预处理point[i]和point[j]两两点之间的距离
到mtx[i][j]
代码如下
#define debug
#ifdef debug
#include
#include "/home/majiao/mb.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXN (256)
#define ll long long
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)
using namespace std;
#ifdef debug
#define show(x...) \
do { \
cout << "\033[31;1m " << #x << " -> "; \
err(x); \
} while (0)
#else
#define show(x...)
#endif
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
namespace FastIO {
char print_f[105];
void read() { }
void print() { putchar('\n'); }
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
x = 0;
char ch = getchar();
ll f = 1;
while (!isdigit(ch)) {
if (ch == '-') f *= -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
read(oth...);
}
template <typename T>
inline void put(T x) {
if(x==0) { putchar('0'); putchar('\n'); return; }
if(x<0) { putchar('-'); x = -x; }
int num=0;
char ch[128];
while(x) ch[++num] = x % 10 + '0', x /= 10;
while(num) putchar(ch[num--]);
putchar('\n');
}
}; // namespace FastIO
using FastIO::read;
using FastIO::put;
int n, m, Q, K;
struct Node {
double x, y;
} a[MAXN];
double mtx[MAXN][MAXN];
inline double dist(double x1, double x2, double y1, double y2) {
double X = x1 - x2, Y = y1 - y2;
return sqrt(X*X + Y*Y);
}
bool canout = false, vis[MAXN];
//判断当前坐标(x,y)是否可以跳出去
#define OUT(x, y) ((x+m>=50) || (x-m)<=-50 || ((y+m>=50) || (y-m)<=-50))
void dfs(int u) {
vis[u] = true;
if(canout) return ;
if(OUT(a[u].x, a[u].y)) {
canout = true;
return ;
}
for(int i=1; i<=n; i++) {
if(vis[i]) continue ;
if(mtx[u][i] <= m) dfs(i); //只跳到够得着的点
}
}
signed main() {
#ifdef debug
freopen("test", "r", stdin);
// freopen("out_main", "w", stdout);
clock_t stime = clock();
#endif
scanf("%d %d ", &n, &m);
vector<int> start; //所有起点
for(int i=1; i<=n; i++) { //预处理所有起点
scanf("%lf %lf ", &a[i].x, &a[i].y);
double td = dist(0, a[i].x, 0, a[i].y);
if(td <= 7.5+m) start.push_back(i);
#if 0
if(dist(0, 0, a[i].x, a[i].y) <= 7.5+m) {
show(dist(0, a[i].x, 0, a[i].y), a[i].x, a[i].y);
start.push_back(i);
}
#endif
}
for(int i=1; i<=n; i++) //预处理任意两点间的距离
for(int j=1; j<=n; j++) {
mtx[i][j] = dist(a[i].x, a[j].x, a[i].y, a[j].y);
}
for(int i=0; i<int(start.size()) && !canout; i++) { //枚举起点dfs即可
memset(vis, false, sizeof(vis));
dfs(start[i]);
}
printf("%s\n", canout ? "Yes" : "No");
#ifdef debug
clock_t etime = clock();
printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
return 0;
}