题目大意:
有T组线段,每组给出N个描述,表示一条线段的2个端点,求是否存在一条直线能够相交与所有的线段。
n≤100
距离|a - b| < 10-8视为同一个点
题解:
规律+叉积:
这题我们其实要找一条满足的直线,就只需要枚举任意2个端点构成的直线是否能够相交于所有的线段,
因为如果你存在一条能够相交所有线段的直线,那么你也就可以将这条直线偏移到端点处,此时必定至少2个端点被经过,注意判断是否<10-8
证明:
http://blog.sina.com.cn/s/blog_6635898a0100n2lv.html
代码:
const
maxn=1e-8;
var
x,y:array [0..101,1..2] of real;
p,q,i,j,n,t:longint;
check:boolean;
function display(x1,y1,x2,y2,x3,y3:real):real;
begin
exit((x1-x3)*(y2-y3)-(x2-x3)*(y1-y3));
end;
function find(x1,y1,x2,y2:real):boolean;
var
i:longint;
begin
if sqrt(sqr(x1-x2)+sqr(y1-y2))<maxn then exit(false);
for i:=1 to n do
if display(x1,y1,x2,y2,x[i,1],y[i,1])*
display(x1,y1,x2,y2,x[i,2],y[i,2])>maxn then exit(false);
exit(true);
end;
begin
readln(t);
while t>=1 do
begin
readln(n);
for i:=1 to n do
readln(x[i,1],y[i,1],x[i,2],y[i,2]);
if n=1
then writeln('Yes!')
else begin
check:=true;
for i:=1 to n-1 do
if check then
for j:=i+1 to n do
if check then
if find(x[i,1],y[i,1],x[j,1],y[j,1]) or
find(x[i,1],y[i,1],x[j,2],y[j,2]) or
find(x[i,2],y[i,2],x[j,1],y[j,1]) or
find(x[i,2],y[i,2],x[j,2],y[j,2])
then check:=false;
if not(check)
then writeln('Yes!')
else writeln('No!');
end;
dec(t);
end;
end.