冒险寮
【题目大意】
给你四个点的坐标表示两条线段的端点,判断两条线段的位置关系:相交、共线、不相交,如果相交则输出交点坐标。
【输入格式】
第一行一个整数N。
接下来N行,每行8个整数表示4个点的坐标。
【输出格式】
首先输出一行“INTERSECTING LINES OUTPUT”,对于每组询问,如果不相交输出“NONE”,共线输出“LINE”,相交输出两个两位小数表示交点的坐标。最后一行以“END OF OUTPUT”结束。
【样例输入】
5
0 0 4 4 0 4 4 0
5 0 7 6 1 0 2 3
5 0 7 6 3 -6 4 -3
2 0 2 27 1 5 18 5
0 3 4 0 1 2 2 5
【样例输出】
POINT 2.00 2.00
NONE
LINE
POINT 2.00 5.00
POINT 1.07 2.20
END OF OUTPUT
【题目分析】
被一个s1+s2打成s1*s2折磨的死去活来
很板,可以当成向量运算的模板题来打。。。利用叉积判一下位置看是否共线或不相交,交点求法可见之前的关于向量运算的博客。
【代码~】
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const double MAXN=15;
struct point{
double x,y;
point(double a=0,double b=0)
{
x=a,y=b;
}
friend inline point operator+(const point &a,const point &b){
return point(a.x+b.x,a.y+b.y);
}
friend inline point operator-(const point &a,const point &b){
return point(a.x-b.x,a.y-b.y);
}
friend inline double dot(const point &a,const point &b){
return a.x*b.x+a.y*b.y;
}
friend inline point fs(point a,double k){
return point(a.x*k,a.y*k);
}
friend inline double operator*(const point &a,const point &b){
return a.x*b.y-a.y*b.x;
}
}a,b,c,d;
int n;
bool on(const point &x,const point &y,const point &z)
{
double det=(x-z)*(y-z);
if(det!=0)
return 0;
return 1;
}
int main()
{
scanf("%d",&n);
puts("INTERSECTING LINES OUTPUT");
while(n--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
double det=(b-a)*(d-c);
if(det==0)
{
if(on(c,d,a))
{
puts("LINE");
continue;
}
puts("NONE");
}
else
{
double s1=(c-a)*(c-d),s2=(c-d)*(c-b);
double k=s1/(s1+s2);
point c=fs(b-a,k);
printf("POINT %.2lf %.2lf\n",a.x+c.x,a.y+c.y);
}
}
puts("END OF OUTPUT");
return 0;
}