UVa 191

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 struct point{
  7     int x,y;
  8     point(int x = 0,int y = 0){
  9         this->x = x;
 10         this->y = y;
 11     }
 12 };
 13 class Intersec{
 14     private:
 15         point ls,lt,c1,c2,c3,c4;
 16     //线段端点和矩形的四个端点
 17     public:
 18         void readData();//读取数据
 19         void process();//处理
 20         bool isIn(point la,point lb,point c1,point c3);//线段是否在矩形内部
 21         bool isCross(point la,point lb,point pa,point pb);//线段是否和矩形相交
 22         int dir(point i,point j,point k);//向量叉积
 23         bool isInSeg(point a,point la,point lb);//点是否在线段l上
 24 };
 25 void Intersec::readData(){//输入数据
 26     int x1,y1,x2,y2,x3,y3,x4,y4;
 27     scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
 28     ls = point(x1,y1);
 29     lt = point(x2,y2);
 30     c1 = point(min(x3,x4),max(y3,y4));
 31     c2 = point(min(x3,x4),min(y3,y4));
 32     c3 = point(max(x3,x4),min(y3,y4));
 33     c4 = point(max(x3,x4),max(y3,y4));
 34 }
 35 void Intersec::process(){
 36     if(isIn(ls,lt,c1,c3))
 37         cout<<"T"<<endl;
 38     else if(isCross(ls,lt,c2,c1)||isCross(ls,lt,c1,c4)||
 39             isCross(ls,lt,c2,c3)||isCross(ls,lt,c3,c4)){
 40         cout<<"T"<<endl;
 41     }
 42     else
 43         cout<<"F"<<endl;
 44 }
 45 
 46 bool Intersec::isIn(point la,point lb,point c1,point c3){//判断线段是否在矩形内
 47     if((min(c1.x,c3.x) <= la.x && la.x <= max(c1.x,c3.x))&&
 48        (min(c1.y,c3.y) <= la.y && la.y <= max(c1.y,c3.y))&&
 49        (min(c1.x,c3.x) <= lb.x && lb.x <= max(c1.x,c3.x))&&
 50        (min(c1.y,c3.y) <= lb.y && lb.y <= max(c1.y,c3.y))){
 51             return true;
 52        }
 53        return false;
 54 }
 55 bool Intersec::isCross(point la,point lb,point pa,point pb){//判断线段是否与矩形相交
 56     int dir1 = dir(pa,pb,la);//判断点la在线段pa--pb的哪一侧,0,1代表两侧
 57     int dir2 = dir(pa,pb,lb);//判断点lb在线段pa--pb的哪一侧,0,1代表两侧
 58     int dir3 = dir(la,lb,pa);//判断点pa在线段la--lb的哪一侧,0,1代表两侧
 59     int dir4 = dir(la,lb,pb);//判断点pb在线段la--lb的哪一侧,0,1代表两侧
 60     if(dir1 * dir2 < 0 && dir3*dir4 < 0){//线段相交
 61         return true;
 62     }
 63     else if(dir1 == 0){//向量共线,判断是否重合
 64         if(isInSeg(pa,pb,la))return true;
 65         return false;
 66     }
 67     else if(dir2 == 0){
 68         if(isInSeg(pa,pb,lb))return true;
 69         return false;
 70     }
 71     else if(dir3 == 0){
 72         if(isInSeg(la,lb,pa))return true;
 73         return false;
 74     }
 75     else if(dir4 == 0){
 76         if(isInSeg(la,lb,pb))return true;
 77         return false;
 78     }
 79     else
 80         return false;
 81 }
 82 int Intersec::dir(point i,point j,point k){//向量叉积
 83     return ((j.x - i.x)*(k.y - i.y)-(k.x - i.x)*(j.y - i.y));
 84 }
 85 bool Intersec::isInSeg(point la,point lb,point a){
 86     if((min(la.x,lb.x) <= a.x && a.x <= max(la.x,lb.x)) &&
 87        (min(la.y,lb.y) <= a.y && a.y <= max(la.y,lb.y)))
 88         return true;
 89     else
 90         return false;
 91 }
 92 int main()
 93 {
 94     #ifndef ONLINE_JUDGE
 95         freopen("D:\\acm.txt","r",stdin);
 96     #endif // ONLINE_JUDGE
 97     int cases;
 98     Intersec intersec;
 99     cin>>cases;
100     while(cases--){
101         intersec.readData();
102         intersec.process();
103     }
104 
105     return 0;
106 }

 

posted @ 2015-11-20 18:15  小白v  阅读(261)  评论(0编辑  收藏  举报