【POJ】2653 - Pick-up sticks (线段香蕉)

题目大意:
按顺序扔下n根棍子,给出棍子的端点坐标,求没有被压住的棍子的序号。



通过快速排斥实验和跨立实验两个方法,判断线段间的关系。

AC代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;

struct stick{
    double x1,x2,y1,y2;
    stick (){};    //构造函数
    stick(int xx1,int xx2,int yy1,int yy2){
        x1 = xx1;
        x2 = xx2;
        y1 = yy1;
        y2 = yy2;
    }
}s[110000];
bool rectangle_is_cross(stick a,stick b){    //快速排斥实验
    if(max(a.x1,a.x2) >= min(b.x1,b.x2) && min(a.x1,a.x2) <= max(b.x1,b.x2) &&
       max(a.y1,a.y2) >= min(b.y1,b.y2) && min(a.y1,a.y2) <= max(b.y1,b.y2))
        return 1;
    else    return 0;
}
bool is_cross(stick a,stick b){    //跨立实验
    if(((a.x1-b.x1)*(b.y2-b.y1)-(a.y1-b.y1)*(b.x2-b.x1))*
        ((b.x2-b.x1)*(a.y2-b.y1)-(b.y2-b.y1)*(a.x2-b.x1)) > 0)
        return 1;
    else    return 0;
}
int main(void){
    int n,cover[110000];
    while(cin>>n && n){
        memset(cover,0,sizeof(cover));
        for(int i=0;i<n;++i){
//          cin>>s[i].x1>>s[i].y1>>s[i].x2>>s[i].y2;
//          cout<<s[i].x1<<s[i].y1<<s[i].x2<<s[i].y2<<endl;
            scanf("%lf %lf %lf %lf",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2);
        }
        for(int i=0;i<n;++i){
            for(int j=i+1;j<n;++j){
                if(!cover[i]){      //未覆盖 
                    if(rectangle_is_cross(s[i],s[j])){      //矩阵相交 
                        if(is_cross(s[i],s[j]) && is_cross(s[j],s[i])){         //相互跨立 
                            cover[i] = 1;                   //i覆盖j 
                            break;
                        }
                    }
                }
            }
        }
        cout<<"Top sticks:";
        bool flag = 1;
        for(int i=0;i<n;++i){
            if(!cover[i]){
                if(flag){
                    cout<<' '<<i+1;
                    flag = 0;
                }
                else cout<<", "<<i+1;
            }
        }
        cout<<'.'<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41009682/article/details/81268287