Urban Design(数学向量,用叉乘判断是否直线与线段相交)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
其实这道题把题意理解清楚了就比较容易写了;
我开始理解错题意了;把他理解成线段经过的区域是否都是same或者different,所以开头就搞错了,一直没有思路;后来补题才发现这个东西:
在这里插入图片描述
这里的they指的是两个点所在的区域。
所以这个题就可以发现这个问题:
在这里插入图片描述
当线段和奇数个直线相交的时候答案是different,偶数个相交的时候是same;所以难点就在如何判断相交上面了;
判断相交可以用向量来判断;
具体分析如下:
在这里插入图片描述
根据右手定则,只要两个叉乘的符号相反就表示CD线段和AB直线相交;
所以AC代码:

#include<bits/stdc++.h>
using namespace std;
struct Point{
    
    
	int x,y;
	Point(int xx,int yy){
    
    
		  x=xx;y=yy;
	} 
	Point(){
    
    }
	int operator^(Point b){
    
    //重载的叉积
	     return x*b.y-b.x*y;  
	}
	Point operator-(Point b){
    
    
	     return Point(x-b.x,y-b.y);
	}
}p[20050],s,e;
bool intersect(Point A,Point B,Point C,Point D){
    
    
	Point AB=B-A;
	int t1=AB^(C-A);
	int t2=AB^(D-A);
	if((t1>0&&t2<0)||(t1<0&&t2>0)) return true;//判断是否相交
	else return false;
}
int main(){
    
    
	int S;
	scanf("%d",&S);
	int g=0;
	for(int i=0;i<S;i++){
    
    
		  scanf("%d %d %d %d",&p[g].x,&p[g].y,&p[g+1].x,&p[g+1].y);
		  g+=2;
	}
	int T;
	scanf("%d",&T);
	for(int i=0;i<T;i++){
    
    
		int num=0;
		   scanf("%d %d %d %d",&s.x,&s.y,&e.x,&e.y);
		   for(int j=0;j<g;j+=2){
    
    
		   	  if(intersect(p[j],p[j+1],s,e)){
    
    
		   	  	     num++;
				 }
		   }
		   if(num&1){
    
    
		   	  puts("different");
		   }else{
    
    
		   	  puts("same");
		   }
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_44555205/article/details/104579631