如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。
URAL/1062
来自"NOCOW"
< URAL
假设我们要让第一个运动员赢得比赛,则必须满足不等式组
L1/v1+L2/u1+L3/w1<L1/v2+L2/u2+L3/w2
L1/v1+L2/u1+L3/w1<L1/v3+L2/u3+L3/w3
L1/v1+L2/u1+L3/w1<L1/v4+L2/u4+L3/w4
…………
L1/v1+L2/u1+L3/w1<L1/vn+L2/un+L3/wn
看L1,L2,L3是否有解即可,将不等式变形
L1/v1+L2/u1+L3/w1<L1/v2+L2/u2+L3/w2
变为
L1/(L3*v1)+L2/(L3*u1)+1/w1<L1/(L3*v2)+L2/(L3*u2)+1/w2
以此类推,那么很显然以L1/L3,L2/L3为元,做半平面交,如果面积大于0则有解,否则无解
program cao; const maxn=200; bignum=maxlongint; eps=1e-10; type Tpoint=record x,y:extended; end; Thalf_plane=record a,b,c:extended; end; THPI=object //half plane intersection total,tot:longint; p,q:array[1..maxn] of Tpoint; procedure init; function intersect(u,v:Tpoint;tmp:Thalf_plane):Tpoint; procedure cut(tmp:Thalf_plane); function ok:boolean; end; var t:THPI; a,b,c,d,e,f,g,h,i,j,k,l,n,m,p,q:longint; s1,s2,s3:array[0..maxn] of longint; tmp:Thalf_plane; procedure THPI.init; begin total:=4; p[1].x:=0; p[1].y:=0; p[2].x:=bignum; p[2].y:=0; p[3].x:=bignum; p[3].y:=bignum; p[4].x:=0; p[4].y:=bignum; end; function THPI.intersect(u,v:Tpoint;tmp:Thalf_plane):Tpoint; var ans:Tpoint; t1,t2,delta:extended; begin t1:=tmp.a*u.x+tmp.b*u.y+tmp.c; t2:=tmp.a*v.x+tmp.b*v.y+tmp.c; delta:=-t1/t2; ans.x:=(u.x+delta*v.x)/(1+delta); ans.y:=(u.y+delta*v.y)/(1+delta); exit(ans); end; procedure THPI.cut(tmp:Thalf_plane); var i,j:longint; begin tot:=0; if (abs(tmp.a)<eps)and(abs(tmp.b)<eps)and(tmp.c>=-eps) then begin total:=0; exit; end; for i:=1 to total do begin if tmp.a*p[i].x+tmp.b*p[i].y+tmp.c<eps then begin inc(tot); q[tot]:=p[i]; end else begin j:=i-1; if j<=0 then j:=total; if tmp.a*p[j].x+tmp.b*p[j].y+tmp.c<-eps then begin inc(tot); q[tot]:=intersect(p[j],p[i],tmp); end; j:=i+1; if j>total then j:=1; if tmp.a*p[j].x+tmp.b*p[j].y+tmp.c<-eps then begin inc(tot); q[tot]:=intersect(p[i],p[j],tmp); end; end; end; total:=tot; move(q[1],p[1],sizeof(Tpoint)*tot); end; function THPI.ok:boolean; begin exit(total>=3); end; procedure init; begin read(n); for i:=1 to n do read(s1[i],s2[i],s3[i]); end; procedure main; begin for i:=1 to n do begin t.init; for j:=1 to n do if i<>j then begin tmp.a:=1/s1[i]-1/s1[j]; tmp.b:=1/s2[i]-1/s2[j]; tmp.c:=1/s3[i]-1/s3[j]; t.cut(tmp); if t.ok=false then break; end; if t.ok then writeln(‘Yes’) else writeln(‘No’); end; end; begin init; main; end.
弱弱的枚举也过了哦
#include <iostream> using namespace std; long n,i,j,k,l,okk,flag,x[101],y[101],z[101],ok[101]; double ct,best; double bbs (double now) { if (now>0) return (now); else return (0-now); } int main () { cin>>n; for (i=0;i<n;i++) cin>>x[i]>>y[i]>>z[i]; for (j=0;j<=500;j++) for (k=0;k<=500-j;k++) { l=500-j-k; best=10000000.00000; flag=1; for (i=0;i<n;i++) { ct=(double)(j)/(double)(x[i])+(double)(k)/(double)(y[i])+(double)(l)/(double)(z[i]); if (bbs(ct-best)<0.000000000001) { flag=0; continue; } if (ct<best) { flag=1; best=ct; okk=i; } } if (flag) ok[okk]=1; } for (i=0;i<n;i++) if (ok[i]) cout<<"Yes"<<endl; else cout<<"No"<<endl; return (0); }