UVa 191

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
struct point{
    int x,y;
    point(int x = 0,int y = 0){
        this->x = x;
        this->y = y;
    }
};
class Intersec{
    private:
        point ls,lt,c1,c2,c3,c4;
    //线段端点和矩形的四个端点
    public:
        void readData();//读取数据
        void process();//处理
        bool isIn(point la,point lb,point c1,point c3);//线段是否在矩形内部
        bool isCross(point la,point lb,point pa,point pb);//线段是否和矩形相交
        int dir(point i,point j,point k);//向量叉积
        bool isInSeg(point a,point la,point lb);//点是否在线段l上
};
void Intersec::readData(){//输入数据
    int x1,y1,x2,y2,x3,y3,x4,y4;
    scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
    ls = point(x1,y1);
    lt = point(x2,y2);
    c1 = point(min(x3,x4),max(y3,y4));
    c2 = point(min(x3,x4),min(y3,y4));
    c3 = point(max(x3,x4),min(y3,y4));
    c4 = point(max(x3,x4),max(y3,y4));
}
void Intersec::process(){
    if(isIn(ls,lt,c1,c3))
        cout<<"T"<<endl;
    else if(isCross(ls,lt,c2,c1)||isCross(ls,lt,c1,c4)||
            isCross(ls,lt,c2,c3)||isCross(ls,lt,c3,c4)){
        cout<<"T"<<endl;
    }
    else
        cout<<"F"<<endl;
}

bool Intersec::isIn(point la,point lb,point c1,point c3){//判断线段是否在矩形内
    if((min(c1.x,c3.x) <= la.x && la.x <= max(c1.x,c3.x))&&
       (min(c1.y,c3.y) <= la.y && la.y <= max(c1.y,c3.y))&&
       (min(c1.x,c3.x) <= lb.x && lb.x <= max(c1.x,c3.x))&&
       (min(c1.y,c3.y) <= lb.y && lb.y <= max(c1.y,c3.y))){
            return true;
       }
       return false;
}
bool Intersec::isCross(point la,point lb,point pa,point pb){//判断线段是否与矩形相交
    int dir1 = dir(pa,pb,la);//判断点la在线段pa--pb的哪一侧,0,1代表两侧
    int dir2 = dir(pa,pb,lb);//判断点lb在线段pa--pb的哪一侧,0,1代表两侧
    int dir3 = dir(la,lb,pa);//判断点pa在线段la--lb的哪一侧,0,1代表两侧
    int dir4 = dir(la,lb,pb);//判断点pb在线段la--lb的哪一侧,0,1代表两侧
    if(dir1 * dir2 < 0 && dir3*dir4 < 0){//线段相交
        return true;
    }
    else if(dir1 == 0){//向量共线,判断是否重合
        if(isInSeg(pa,pb,la))return true;
        return false;
    }
    else if(dir2 == 0){
        if(isInSeg(pa,pb,lb))return true;
        return false;
    }
    else if(dir3 == 0){
        if(isInSeg(la,lb,pa))return true;
        return false;
    }
    else if(dir4 == 0){
        if(isInSeg(la,lb,pb))return true;
        return false;
    }
    else
        return false;
}
int Intersec::dir(point i,point j,point k){//向量叉积
    return ((j.x - i.x)*(k.y - i.y)-(k.x - i.x)*(j.y - i.y));
}
bool Intersec::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;
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("D:\\acm.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int cases;
    Intersec intersec;
    cin>>cases;
    while(cases--){
        intersec.readData();
        intersec.process();
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值