线段判非严格相交+暴力——poj2653

O(n2)的暴力居然能过。。

#include
#include
#include
#include
using namespace std;
#define N 200005
#define db double

const db eps=1e-6;
int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;}
int cmp(db k1,db k2){return sign(k1-k2);}

struct point{
    db x,y;
    point(){}
    point(db x,db y):x(x),y(y){}
    point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    point operator * (db k1) const{return (point){x*k1,y*k1};}
    point operator / (db k1) const{return (point){x/k1,y/k1};}
};
struct line{
    point p[2];
};
db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
int intersect(db l1,db r1,db l2,db r2){//跨立实验 
    if(l1>r1)swap(l1,r1);if(l2>r2)swap(l2,r2);
    return cmp(r1,l2)!=-1 && cmp(r2,l1)!=-1;
}
int checkSS(point k1,point k2,point k3,point k4){
    return intersect(k1.x,k2.x,k3.x,k4.x) && intersect(k1.y,k2.y,k3.y,k4.y) &&
    sign(cross(k3-k1,k4-k1))*sign(cross(k3-k2,k4-k2))<=0 &&
    sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<=0;
}

point p[N];
line l[N];
int n,vis[N],totp;

int main(){
    while(scanf("%d",&n) && n){
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n;i++){
            point k1,k2;
            scanf("%lf%lf",&k1.x,&k1.y);
            scanf("%lf%lf",&k2.x,&k2.y);
            p[++totp]=k1;p[++totp]=k2;
            l[i].p[0]=k1;l[i].p[1]=k2;
        }
        for(int i=1;i<=n;i++){
            int flag=0; 
            for(int j=i+1;j<=n;j++)
                if(checkSS(l[i].p[0],l[i].p[1],l[j].p[0],l[j].p[1])){
                    flag=1;break;
                }
            if(!flag)vis[i]=1;
        } 
        
        int flag=0;
        cout<<"Top sticks: ";
        for(int i=1;i<=n;i++)if(vis[i]){
            if(flag==0){
                cout<<i;
                flag=1;
            }
            else {
                cout<<", "<<i;
            }
        }
        puts(".");
    }    
}

 

你可能感兴趣的:(线段判非严格相交+暴力——poj2653)