题意 : 给你每个人在每一段的速度,让你求出是否存在一种路程的安排使得这个人可以赢得这场比赛
题解 :可以去列方程组,然后发现是一个三维的变元,但是发现有一个变元,可以除过去就成了一个二元方程就是一个二维平面然后判断一个线性方程式组是否存在可行域.
发一个求线性区域的可行区域的模版
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps = 1e-16;
const double inf = 1e9 + 5;
const int maxn = 1505;
struct Point{
double x,y;
}p[maxn],tp[maxn],q[maxn];
struct Node{
double u,v,w;
}z[maxn];
double ab (double x) {return x > 0 ? x : -x;}
double xmul(Point p0,Point p1,Point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
Point Intersection(Point p1,Point p2,double a,double b,double c){
double u = ab(a*p1.x+b*p1.y+c);
double v = ab(a*p2.x+b*p2.y+c);
Point t;
t.x=(p1.x*v+p2.x*u)/(u+v);t.y=(p1.y*v+p2.y*u)/(u+v);
return t;
}
double Get_area(Point p[],int n){
double area=0;
for(int i=2;i<n;i++)
area+=xmul(p[1],p[i],p[i+1]);
return -area/2.0;
}
void Cut(double a,double b,double c,Point p[],int &cnt){
int tmp=0;
for (int i=1;i <= cnt;i++){
if(a*p[i].x+b*p[i].y+c>-eps) tp[++tmp]=p[i];
else{
if(a*p[i-1].x+b*p[i-1].y+c>eps)
tp[++tmp]=Intersection(p[i-1],p[i],a,b,c);
if(a*p[i+1].x+b*p[i+1].y+c>eps)
tp[++tmp]=Intersection(p[i],p[i+1],a,b,c);
}
}
for(int i=1;i<=tmp;i++)
p[i]=tp[i];
p[0]=p[tmp];p[tmp+1]=p[1];
cnt=tmp;
}
int slove(int n,int idx) {
p[1].x=0;p[1].y=0;
p[2].x=0;p[2].y=inf;
p[3].x=inf;p[3].y=inf;
p[4].x=inf;p[4].y=0;
p[0]=p[4];p[5]=p[1];
int cnt=4;
for(int i=0;i<n;i++){
if(i==idx) continue;
double a,b,c;
a=(z[idx].u-z[i].u)/(z[idx].u*z[i].u);
b=(z[idx].v-z[i].v)/(z[idx].v*z[i].v);
c=(z[idx].w-z[i].w)/(z[idx].w*z[i].w);
if(a==0 && b==0&&c<eps) return 0;
Cut(a,b,c,p,cnt);
}
return ab (Get_area(p, cnt)) >= eps;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++)
scanf("%lf%lf%lf",&z[i].u,&z[i].v,&z[i].w);
for(int i=0;i<n;i++)
puts(slove(n,i)?"Yes":"No");
}
return 0;
}