UVa 10902 Pick-up Sticks

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
#define MAXN 100002
struct point {
    double x,y;
    point (double x = 0 ,double y = 0){
        this->x = x;
        this->y = y;
    }
};
struct line{
    point st,en;
    line(point st,point en){
        this->st = st;
        this->en = en;
    }
};
class Isolated{
    private:
        int segNum;
        vector<line> segments;
        int ans[MAXN];
        int ansNum;
    public:
        void init();
        void readData(int num);
        void process();
        bool isCross(line la,line lb);
        bool isInSeg(point a,point la,point lb);//点是否在线段l上
        long long dir(point i,point j,point k);//向量叉积
};
void Isolated::init(){
    ansNum = 0;
    segments.clear();
}
void Isolated::readData(int num){
    segNum = num;
    double x1,y1,x2,y2;
    while(num--){
        scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
        point st(x1,y1),en(x2,y2);
        line la(st,en);
        segments.push_back(la);
    }
}
void Isolated::process(){
    bool isColl;//线段是否是孤立的
    for(int i = 0;i < segNum;i++){
        isColl = true;
        for(int j = segNum - 1;j >= 0;j--){
            if(i==j)continue;
            else{
                if(isCross(segments[i],segments[j])){
                    if(i < j){//如果和之后落下的相交,那么就被排除
                        isColl = false;
                    }break;
                }
            }
        }
        if(isColl)
        {
            ans[ansNum++] = i + 1;
        }
    }
    cout<<"Top sticks: ";
    for(int k = 0; k < ansNum;k++){
        if(k < ansNum - 1)
            cout<<ans[k]<<", ";
        else
            cout<<ans[k]<<"."<<endl;
    }
}
bool Isolated::isCross(line la,line lb){
    long long dir1 = dir(la.st,la.en,lb.st);
    long long dir2 = dir(la.st,la.en,lb.en);
    long long dir3 = dir(lb.st,lb.en,la.st);
    long long dir4 = dir(lb.st,lb.en,la.en);
    if(dir1 * dir2 < 0 && dir3*dir4 < 0){// 线段 相交
        return true;
    }
    else if(dir1 == 0&& isInSeg(la.st,la.en,lb.st)){//向量共线,判断是否重合
        return true;
    }
    else if(dir2 == 0&&isInSeg(la.st,la.en,lb.en)){
        return true;
    }
    else if(dir3 == 0&&isInSeg(lb.st,lb.en,la.st)){
        return true;
    }
    else if(dir4 == 0&&isInSeg(lb.st,lb.en,la.en)){
        return true;
        //return false;
    }
    else
        return false;
}
bool Isolated::isInSeg(point la,point lb,point a){
    if((min(la.x,lb.x) <= a.x && a.x <= max(la.x,lb.x)) &&
       (min(la.y,lb.y) <= a.y && a.y <= max(la.y,lb.y)))
        return true;
    else
        return false;
}
long long Isolated::dir(point i,point j,point k){//向量叉积
    return ((j.x - i.x)*(k.y - i.y)-(k.x - i.x)*(j.y - i.y));
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("D:\\acm.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int cases;

    Isolated isolated;
    while(cin>>cases,cases != 0){
        isolated.init();
        isolated.readData(cases);
        isolated.process();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值