BZOJ 3800 Saber VS Lancer/POJ 1755 Triathlon
N people have a fixed speed for these three sports, but the length of each sport is unknown. Now, I am wondering if the referee can adjust the length of the three sports to win a single player.
Thought: Now, when we want to win a person, the three speeds for this person are v1, v2, and v3, respectively, and we want everyone to lose to him, set the speed of a person to v1, v2, and v3 '. Set the length of the three matches to l1, l2, and l3. It is not difficult to obtain the following equation: l1/v1 + l2/v2 + l3/v3 <l1/v1 '+ l2/v2' + l3/v3 '.
But this equation has three unknowns. What is this? It cannot be processed at all. In fact, this question only requires us to determine whether there is a solution, so we do not pay attention to the specific value. If a solution of X, Y, and Z allows a person to win everyone, then X * K, Y * K, and Z * K can also win everyone. Therefore, determining an l value does not affect the correctness of the answer. So suppose l3 is 1, then l3/v3 and l3/v3 are two values.
The original equation becomes: (for ease of understanding, set x = l1, y = l2) x * (v1 '-v1)/(v1 * v1 ') + y * (v2 '-v2)/(v2 * v2') + k-k' <0.
In this formula, we only do not know xy, and the rest are constants. This is a half plane of x and y. Finding all the Half Planes and determining whether the kernel exists is the answer.
The data range is very small. We can use the semi-plane intersection of O (n ^ 2.
However, I did not have this question .. The accuracy of this question card is simply unbearable. After obtaining data from the Internet, we use cena for testing. There are a total of 25 points, that is, there are two points that cannot survive or survive .. In my heart, AC ..
CODE (not AC, submit with caution ):
#include
#include
#include
#include
#include #define MAX 10010#define EPS 1e-16#define INF (1ll << 32)using namespace std;#define DCMP(a) (fabs(a) < EPS) struct Complex{ double v1,v2,v3; void Read() { scanf("%lf%lf%lf",&v1,&v2,&v3); }}src[MAX]; struct Point{ double x,y; Point(double _ = .0,double __ = .0):x(_),y(__) {} Point operator +(const Point &a)const { return Point(x + a.x,y + a.y); } Point operator -(const Point &a)const { return Point(x - a.x,y - a.y); } Point operator *(double a)const { return Point(x * a,y * a); }}p[MAX]; struct Line{ Point p,v; double alpha; bool operator <(const Line &a)const { return alpha < a.alpha; } Line(Point _,Point __):p(_),v(__) { alpha = atan2(v.y,v.x); } Line() {}}line[MAX],q[MAX]; int cnt,lines; inline double Cross(const Point &a,const Point &b){ return a.x * b.y - a.y * b.x;} inline bool OnLeft(const Line &l,const Point &p){ return Cross(l.v,p - l.p) > 0;} inline void MakeLine(const Complex &win,const Complex &lose){ double A = (lose.v1 - win.v1) / (win.v1 * lose.v1); double B = (lose.v2 - win.v2) / (win.v2 * lose.v2); double C = (lose.v3 - win.v3) / (win.v3 * lose.v3); if(DCMP(A) && DCMP(B) && C < EPS) throw false; if(DCMP(B)) B = EPS; line[++lines] = Line(Point(.0,-C / B),Point(-B,A));} inline void Initialize(){ line[++lines] = Line(Point(0,0),Point(1,0)); line[++lines] = Line(Point(INF,0),Point(0,1)); line[++lines] = Line(Point(INF,INF),Point(-1,0)); line[++lines] = Line(Point(0,INF),Point(0,-1)); } inline Point GetIntersection(const Line &a,const Line &b){ Point u = a.p - b.p; double temp = Cross(b.v,u) / Cross(a.v,b.v); return a.p + a.v * temp;} inline bool HalfplaneIntersection(){ int front = 1,tail = 1; q[1] = line[1]; for(int i = 2;i <= lines; ++i) { while(front < tail && !OnLeft(line[i],p[tail - 1])) --tail; while(front < tail && !OnLeft(line[i],p[front])) ++front; if(DCMP(Cross(line[i].v,q[tail].v))) q[tail] = OnLeft(q[tail],line[i].p) ? line[i]:q[tail]; else q[++tail] = line[i]; if(front < tail) p[tail - 1] = GetIntersection(q[tail],q[tail - 1]); } while(front < tail && !OnLeft(q[front],p[tail - 1])) --tail; if(tail - front <= 1) return false; double re = Cross(tail,front); for(int i = front; i < tail; ++i) re += Cross(p[i],p[i + 1]); return !DCMP(re);} int main(){ cin >> cnt; for(int i = 1; i <= cnt; ++i) src[i].Read(); for(int i = 1; i <= cnt; ++i) { lines = 0; try{ for(int j = 1; j <= cnt; ++j) { if(i == j) continue; MakeLine(src[i],src[j]); } } catch(bool flag) { puts("No"); continue; } Initialize(); sort(line + 1,line + lines + 1); if(HalfplaneIntersection()) puts("Yes"); else puts("No"); } return 0;}