Time Limit:3000MS | Memory Limit:Unknown | 64bit IO Format:%lld & %llu |
Description
![Download as PDF Download as PDF](https://icpcarchive.ecs.baylor.edu/components/com_onlinejudge/images/button_pdf.png)
Korea's reputation in archery is well known because the Korean archery teams have been sweeping almost all gold, silver, and bronze medals in the Olympic Games.
An archery game ICPC supported by NEXON (one of Korea's leading publishers of online contents) will be held in Korea. As a ceremonial event of the game, a famous master of archery will shoot an arrow to hit through all target boards made of paper. Because an arrow flies along a straight line, it depends on his position of the archer line whether or not he hits all targets.
The figure below shows an example of the complete view of a game field from the sky. Every target is represented by a line segment parallel to the archer line. Imagine the coordinate system of which the origin is the leftmost point of the archer line and the archer line is located on the positive x -axis.
![\epsfbox{p4253.eps}](https://icpcarchive.ecs.baylor.edu/external/42/p4253.png)
In the above figure, the master can hit all targets in position B. However, he never hits all targets in positionA because any ray from A intersects at most 3 targets.
Given the width of the archer line and the target locations, write a program for determining if there exists a position at which the master can hit all targets. You may assume that they -coordinates of all targets are different. Note that if an arrow passes through an end point of a target, it is considered to hit that target.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test cases T(1T
30) is given in the first line of the input. Each test case starts with a line containing an integerW(2
W
10, 000, 000) , the width of an archer line. The next line contains an integerN(2
N
5, 000) , the number of target boards. The i -th line of the followingN lines contains three integers Di , Li ,Ri(1
Di
W, 0
Li <Ri
W) , where1
i
N , Di represents the y -coordinate of the i -th target, andLi and Ri represent thex -coordinates of the leftmost point and the rightmost point of the target, respectively. Note thatDi
Dj ifi
j .
Output
Your program is to write to standard output. Print exactly one line for each test case. Print ``YES" if there exists a position on the archer line at which a master of archery can hit all targets, otherwise, ``NO".
The following shows sample input and output for three test cases.
Sample Input
3 15 4 10 2 7 7 5 12 2 7 12 4 9 13 6 3 2 1 3 4 0 2 5 4 6 10 4 8 2 5 4 2 5 6 5 8 2 5 8
Sample Output
YES NO YES
题意:有n个平行于x轴的线段,每条线段代表一个靶子。任务是判断是否可以站在x轴上的[0,W]区间内的某个点射箭,使得能够穿过所有靶子,不同靶子高度y不同
思路:
首先想一个问题:怎么判断站在一个点x射箭能否射穿所有靶子?
对于一个靶子i[Li,Ri],在x点要射穿他,那么箭的角度是一个区间
这样的话,直接求出每个靶子的角度区间,然后维护当前满足所有靶子的区间。
分析会发现其中一个特点,如果一个靶子的区间为[130, 145] 而当前区间为[90, 120] 则当前位置x不能射穿所有靶子。则x需要向做移动,反之向右移动。
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 5000 + 20;
int n;
double w;
struct Line {
double d, l, r;
bool operator < (const Line & b) const {
return d < b.d;
}
};
Line lines[maxn];
int judge(double p) {
double L = 0;
double R = INF;
for(int i=0; i<n; i++) {
double tL = atan2(lines[i].d, lines[i].r - p);
double tR = atan2(lines[i].d, lines[i].l - p);
if(L - tR > eps) return 0;
if(tL - R > eps) return 1;
L = max(L, tL);
R = min(R, tR);
}
return 3;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%lf%d", &w, &n);
for(int i=0; i<n; i++) {
scanf("%lf%lf%lf", &lines[i].d, &lines[i].l, &lines[i].r);
}
sort(lines, lines+n);
int ans = 0;
double L=0, R=w;
while(R - L > eps) {
double mid = (L + R) / 2;
int res = judge(mid);
if(res == 3) {
ans = 1;
break;
} else if(res == 1) L = mid;
else R = mid;
}
if(ans) puts("YES");
else puts("NO");
}
return 0;
}