POJ 3304 Segments

给n条线段,问是否存在一条直线,所有线段在直线上的投影有公共点

这个问题等价于:是否存在一条直线,与所有线段都有交点

证明思路:首先,如果线段AB在直线L上的投影为A'B',那么A'B'之间的任意点C',过它做L的垂线,与AB必然有交点,同样的,AB之间的任意点C,过它做AB的垂线,与A'B'必然有交点。这个结论可以推广到N条线段,那么如果N条线段在某条直线上的投影有公共点,过这个公共点做这条直线的垂线,该垂线必然与N条线段都相交。反过来也一样。

所以,我们只要找到一条直线与N条线段都相交,那么,做这条直线的垂线,就能找到题目要求的那条直线

至于怎么找与N条线段都相交的直线,我们可以枚举每条线段的两个端点,理由如下:假设直线L现在与N条直线都相交,那么将L平移,直到它不能与N条线段相交,那么现在它至少与一条线段的端点(临界点)相交,此时再把这个端点作为固定点,将L旋转,直到它不能与N条线段相交,那么此时L又必然会与至少一条线段的端点相交,这个两个端点就能找出L了

但要注意的是如果两个端点相同,则视为一个点,不能当作直线,以及N=1要特判


http://blog.csdn.net/Once_HNU/article/details/6327906

http://blog.sina.com.cn/s/blog_6635898a0100n2lv.html

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAX=105;
const double eps=1e-8;
struct Point
{
    double x,y;
    Point(){};
    Point(double x,double y):x(x),y(y){};
};
struct Vector
{
    Point a,b;
    Vector(){};
    Vector(Point x,Point y):a(x),b(y){};
}line[MAX];
int n;
double cross(Point a,Point b,Point c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
bool ok(Point a,Point b)
{
    if(a.x==b.x&&a.y==b.y)
        return false;
    for(int i=0;ieps)
            return false;
    }
    return true;
}
int main()
{
    int i,j,T;
    double x1,y1,x2,y2;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        bool flag=false;
        for(i=0;i


你可能感兴趣的:(计算几何)