POJ 1410 Intersection(计算几何)
题目大意:题目意思很简单,就是说有一个矩阵是实心的,给出一条线段,问线段和矩阵是否相交
解题思路:用到了线段与线段是否交叉,然后再判断线段是否在矩阵里面,这里要注意的是,他给出的矩阵的坐标明显不是左上和右下的坐标,需要自己去判断下左上点与右下点的坐标。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; typedef long long ll; #define prN printf("\n") #define SI(N) scanf("%d",&(N)) #define SII(N,M) scanf("%d%d",&(N),&(M)) #define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K)) #define cle(a,val) memset(a,(val),sizeof(a)) #define rep(i,b) for(int i=0;i<(b);i++) #define Rep(i,a,b) for(int i=(a);i<=(b);i++) #define reRep(i,a,b) for(int i=(a);i>=(b);i--) const double eps = 1e-8; //判断doubule型的正负或0 int sgn(double x) { if(fabs(x) < eps)return 0; if(x < 0) return -1; else return 1; } //构建点,且重载运算符 struct Point { double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } //重载减号 因为在求两个点相减构成一个向量时候会用到 Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } //这是叉积运算,很重要,不多说 double operator ^(const Point &b)const { return x*b.y - y*b.x; } double operator *(const Point &b)const { return x*b.x + y*b.y; } }; struct Line { Point s,e; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; } }; //判断线段相交 bool inter(Line l1,Line l2) { return //这是2个矩形是否相交 max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) && //这是判断叉积异号 sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= 0 && sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= 0; } //求距离 double dist(Point a,Point b) { return sqrt((b-a)*(b-a)); } int n; Line line[4]; Line endli; double a1,a2,a3,a4,xtop,ytop,xbott,ybott; int main() { #ifndef ONLINE_JUDGE freopen("C:\\Users\\Zmy\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\Zmy\\Desktop\\out.txt","w",stdout); #endif // ONLINE_JUDGE SI(n); rep(t,n) { scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a1,&a2,&a3,&a4,&xtop,&ytop,&xbott,&ybott); endli=Line(Point(a1,a2),Point(a3,a4)); //把4条边存进line里 line[0]=Line(Point(xtop,ytop),Point(xtop,ybott)); line[1]=Line(Point(xtop,ytop),Point(xbott,ytop)); line[2]=Line(Point(xtop,ybott),Point(xbott,ybott)); line[3]=Line(Point(xbott,ytop),Point(xbott,ybott)); int fl=0; //判断两条线是否相交 rep(i,4) { if (inter(line[i],endli)) { fl=1;break; } } //判断是否在矩形内 if (max(a1,a3)<max(xbott,xtop)&&min(a1,a3)>min(xbott,xtop)&&max(a2,a4)<max(ytop,ybott)&&min(a2,a4)>min(ytop,ybott)) { fl=1; } if (fl) puts("T"); else puts("F"); } return 0; }