poj1410 - Intersection

133 篇文章 0 订阅

                                 想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410
                                  转载请注明出处:
http://blog.csdn.net/wangjian8006

题目大意:题目意思很简单,就是说有一个矩阵是实心的,给出一条线段,问线段和矩阵是否相交
解题思路:用到了线段与线段是否交叉,然后再判断线段是否在矩阵里面,这里要注意的是,他给出的矩阵的坐标明显不是左上和右下的坐标,需要自己去判断下左上点与右下点的坐标。

 

/*
Memory 188K
Time    0MS 
*/
#include <stdio.h>
#define min(a,b) (a>b?b:a)
#define max(a,b) (a<b?b:a)

typedef struct{
    double x1,y1,x2,y2;
}Line;

Line line,line2;
double x1,x2,y1,y2;

double direction(double x,double y,double x1,double y1,double x2,double y2){
    double a1=x1-x;
    double b1=y1-y;
    double a2=x2-x;
    double b2=y2-y;
    return a1*b2-a2*b1;
}

int on_segment(double x1,double y1,double x2,double y2,double x,double y){
    if((min(x1,x2)<=x && x<=max(x1,x2)) && (min(y1,y2)<=y && y<=max(y1,y2)))
        return 1;
    return 0;
}

int cross(Line v,Line t){
    double d1,d2,d3,d4;
    d1=direction(t.x1,t.y1,t.x2,t.y2,v.x1,v.y1);
    d2=direction(t.x1,t.y1,t.x2,t.y2,v.x2,v.y2);
    d3=direction(v.x1,v.y1,v.x2,v.y2,t.x1,t.y1);
    d4=direction(v.x1,v.y1,v.x2,v.y2,t.x2,t.y2);
    if(d1*d2<0 && d3*d4<0) return 1;
    if(!d1 && on_segment(t.x1,t.y1,t.x2,t.y2,v.x1,v.y1)) return 1;
    if(!d2 && on_segment(t.x1,t.y1,t.x2,t.y2,v.x2,v.y2)) return 1;
    if(!d3 && on_segment(v.x1,v.y1,v.x2,v.y2,t.x1,t.y1)) return 1;
    if(!d4 && on_segment(v.x1,v.y1,v.x2,v.y2,t.x2,t.y2)) return 1;
    return 0;
}
int main(){
    int flag,n;
	double tmp;
    scanf("%d",&n);
    while(n--){
        scanf("%lf%lf%lf%lf",&line.x1,&line.y1,&line.x2,&line.y2);
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);

		if(x1>x2){
			tmp=x1,x1=x2,x2=tmp;
		}
		if(y1<y2){
			tmp=y1,y1=y2,y2=tmp;
		}
		
        flag=0;
        line2.x1=x1;
        line2.y1=y1;
        line2.x2=x2;
        line2.y2=y1;
        if(cross(line,line2)) flag=1;
        else{
            line2.x1=x1;
            line2.y1=y1;
            line2.x2=x1;
            line2.y2=y2;
            if(cross(line,line2)) flag=1;
            else{
                line2.x1=x2;
                line2.y1=y1;
                line2.x2=x2;
                line2.y2=y2;
                if(cross(line,line2)) flag=1;
                else{
                    line2.x1=x1;
                    line2.y1=y2;
                    line2.x2=x2;
                    line2.y2=y2;
                    if(cross(line,line2)) flag=1;
                }
            }
        }
        if(flag) printf("T\n");
        else{
            if(x1<min(line.x1,line.x2) && x2>max(line.x1,line.x2) && y1>max(line.y1,line.y2) && y2<min(line.y1,line.y2)) 
                printf("T\n");
            else
                printf("F\n");
        }
    }
    return 0; 
}


====================================================================

 

/*模拟
Memory 252K
Time    0MS
*/
#include<iostream>

#define max(a,b) ((a)>(b)?(a):(b)) 
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;

int xstar,ystar,xend,yend;
int xleft,ytop,xright,ybottom;

bool spot(){
	if((xstar<=xright && xstar>=xleft && ystar<=ytop && ystar>=ybottom) || (xend<=xright && xend>=xleft && yend<=ytop 

&& yend>=ybottom))
		return true;
	return false;
} 

bool line(){
	double tmp;
	double k;
	//考虑斜率不存在的情况
	if(xstar==xend && xstar<=xright && xstar>=xleft && ytop<=max(ystar,yend) && ytop>=min(ystar,yend)) return true;
	if(xstar==xend) return false;
	
	k=1.0*(ystar-yend)/(xstar-xend);
	
	//与矩形上边相交
	tmp=1.0*(ytop-ystar)/k+xstar;
	if(ytop<=max(ystar,yend) && ytop>=min(ystar,yend) && tmp<=xright && tmp>=xleft) return true;
	//与矩形下边相交
	tmp=1.0*(ybottom-ystar)/k+xstar;
	if(ybottom<=max(ystar,yend) && ybottom>=min(ystar,yend) && tmp<=xright && tmp>=xleft) return true;
	//与矩形左边相交
	tmp=1.0*k*(xleft-xstar)+ystar;
	if (xleft<=max(xstar,xend) && xleft>=min(xstar,xend) && tmp<=ytop && tmp>=ybottom) return true;
	//与矩形右边相交
	tmp=1.0*k*(xright-xstar)+ystar;
	if (xright<=max(xstar,xend) && xright>=min(xstar,xend) && tmp<=ytop && tmp>=ybottom) return true;
	
	return false;
}

int main(){
	int t,tmp;
	cin>>t;
	while(t--){
		cin>>xstar>>ystar>>xend>>yend;
		cin>>xleft>>ytop>>xright>>ybottom;
		
		if(xleft>xright){
			tmp=xleft;
			xleft=xright;
			xright=tmp;
		}
		if(ybottom>ytop){
			tmp=ybottom;
			ybottom=ytop;
			ytop=tmp;
		}
		
		if(spot())		//如果端点在矩形的内部
			cout<<'T'<<endl;
		else if(line())		//如果线段和四条边相交
			cout<<'T'<<endl;
		else cout<<'F'<<endl;
	}
	return 0;
}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值