之前的半平面交一直建立在多边形的基础上,因此遇到更一般的线性规划就显得有点措手不及。。
先讲一下线性规划的思路吧:
首先是把方程转化为半平面,这对用n^2的人来说并不难。。他们只需要用到直线方程。。
然而对使用nlogn的人来说,需要的反而是直线上的2点,这种逆变换感觉并没有什么优雅的姿势去解决。。
窝是这么解的。。首先先找出半平面的方向,即倾斜角k。。然后再找特殊点,在特殊点的基础之上分别加上cost和sint即可。。
然后倾斜角t要怎么找。。这里用图解可能会方便点。。。以Ax+By+C<0为例:
这里用到了直线方程的另外一种理解,点乘为定值的集合,这样可以通过向量n迅速找到和t的关系,将n旋转90度后倾斜角就已经是t了,所以t=atan2(-B,A)
特殊点窝取了y=0,考虑直线和y垂直的情况,需要特判一下才能取特殊点。。
转化为半平面后直接半平面交吧。。
然后来看看这题。。
设3个路程分别为a,b,c的话。。题目的要求应该是对每个人t,看是否满足
a/u[t]+b/w[t]+c/v[t]<=a/u[i]+b/w[i]+c/v[i] i=1~n
当且仅当i==t等号成立
然后发现是3个未知数。。怕不是要来个三维的。。
其实很容易发现该式是个齐次式,同除c可以得到
a/c/u[t]+b/c/w[t]+1/v[t]<=a/c/u[i]+b/c/w[i]+1/v[i]
然后令x=a/c,y=b/c,直接三元降二元。。整理得
(u[i]-u[t])/u[i]/u[t]*y+(w[i]-w[t])/w[i]/w[t]*y+(v[i]-v[t])/v[i]/v[t]<=0
不推荐写1/u[i]-1/u[t]这类。。。貌似容易爆精度。。(评论区一大堆1e-16貌似就是这么来的。。
然后就剩下几个坑点了。。
要注意到题目要的是唯一胜者,交完出来是不是个点还需要特判。。。
另外。。x,y可能会非常大。。inf能开大就尽量开大。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inf 10000005.0
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define ls T[i<<1]
#define rs T[i<<1|1]
#define op T[i]
#define mid (x+y>>1)
#define NM 105
#define nm 100498
#define pi 3.1415926535897931
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
struct P{
double x,y;
P(double x=0,double y=0):x(x),y(y){}
double operator*(const P&o){return x*o.y-y*o.x;}
P operator-(const P&o){return P(x-o.x,y-o.y);}
}p[NM];
double dis(P o){return sqrt(sqr(o.x)+sqr(o.y));}
struct L{double k;P a,b;}l[NM];
int n,m,q[NM],qt,qh,tmp[NM];
double A,B,C,v[NM],u[NM],w[NM];
bool cmp(int x,int y){
if(fabs(l[x].k-l[y].k)<eps)return (l[y].b-l[x].a)*(l[x].b-l[x].a)>eps;
return l[x].k<l[y].k;
}
P intersect(L x,L y){
double t1=(x.b-y.a)*(x.a-y.a),t2=(y.b-x.b)*(x.a-x.b);
return P((y.a.x*t2+y.b.x*t1)/(t1+t2),(y.a.y*t2+y.b.y*t1)/(t1+t2));
}
bool judge(L a,L b,L c){return (a.b-a.a)*(intersect(b,c)-a.a)+eps<0;}
void cut(){
sort(tmp+1,tmp+1+n+3,cmp);m=1;
inc(i,2,n+3)if(fabs(l[tmp[i]].k-l[tmp[m]].k)>eps)tmp[++m]=tmp[i];
mem(q);qh=1;qt=0;
inc(k,1,m){
int i=tmp[k];
while(qh<qt&&judge(l[i],l[q[qt-1]],l[q[qt]]))qt--;
while(qh<qt&&judge(l[i],l[q[qh+1]],l[q[qh]]))qh++;
q[++qt]=i;
}
while(qh<qt&&judge(l[q[qt]],l[q[qh+1]],l[q[qh]]))qh++;
while(qh<qt&&judge(l[q[qh]],l[q[qt-1]],l[q[qt]]))qt--;
}
int main(){
//freopen("data.in","r",stdin);
n=read();
inc(i,1,n)u[i]=read(),w[i]=read(),v[i]=read();
inc(i,1,n){
bool f=true;
inc(j,1,n)if(i!=j){
A=(u[j]-u[i])/u[i]/u[j];
B=(w[j]-w[i])/w[i]/w[j];
C=(v[j]-v[i])/v[i]/v[j];
if(fabs(u[i]-u[j])>eps)l[j].a=P(-C/A,0);
else if(fabs(w[i]-w[j])>eps)l[j].a=P(0,-C/B);
else{
if(C+eps>0){f=false;break;}
l[j].k=0;l[j].a=P(0,0);l[j].b=P(1,0);continue;
}
if(eps+u[j]>u[i]&&eps+w[j]>w[i]&&eps+v[j]>v[i]){f=false;break;}
l[j].k=atan2(A,-B);
l[j].b=P(l[j].a.x+cos(l[j].k),l[j].a.y+sin(l[j].k));
}
if(!f){puts("No");continue;}
l[i].a=P(0,0);l[i].b=P(1,0);l[i].k=0;
l[n+1].a=P(inf,0);l[n+1].b=P(inf,1);l[n+1].k=atan2(1.0,0.0);
l[n+2].a=P(1,inf);l[n+2].b=P(0,inf);l[n+2].k=atan2(0.0,-1.0);
l[n+3].a=P(0,1);l[n+3].b=P(0,0);l[n+3].k=atan2(-1.0,0.0);
inc(i,1,n+3)tmp[i]=i;
cut();
//printf("%d %d %d\n",m,qh,qt);
if(qt<=qh+1){puts("No");continue;}
q[qt+1]=q[qh];m=0;double ans=0;
inc(j,qh,qt)p[++m]=intersect(l[q[j]],l[q[j+1]]);
inc(j,1,m)inc(k,j+1,m)ans=max(ans,dis(p[j]-p[k]));
//printf("%lf\n",ans);
if(ans>eps)puts("Yes");else puts("No");
}
return 0;
}
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7470 | Accepted: 1987 |
Description
The speed of each contestant in all three sections is known. The judge can choose the length of each section arbitrarily provided that no section has zero length. As a result sometimes she could choose their lengths in such a way that some particular contestant would win the competition.
Input
Output
Sample Input
9 10 2 6 10 7 3 5 6 7 3 2 7 6 2 6 3 5 7 8 4 6 10 4 2 1 8 7
Sample Output
Yes Yes Yes No No No Yes No Yes
Source
[Submit] [Go Back] [Status] [Discuss]