Metallic Equipment Rigid(圆与直线关系+向量的运算)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
这道题。。。。。我dug了半天结果没有ll。。。。。。。还有j++写成了j+=2;
我也是生无可恋了。。。。(
题意:给出c个圆的圆心坐标+R,然后给出pp个点,按照输入顺序连线,问:有那些圆和线段相交或圆包含线段,按照编号由小到大输出。
这道题直接用向量来搞定,向量的叉乘+cos角度判断就ok了;
圆与线段的关系肯定就有以下的情况:
在这里插入图片描述
若相交或者圆包含线段的话:
1.两个点中其中任意一点在圆内或者两个点都在圆内,那么肯定线段和圆相交或者圆包含线段;
2.如果两个点在外面
         (1)如果两个绿色的角都是锐角,或者其中一个为直角:
在这里插入图片描述

            (2)如果其中一个绿角为钝角,那么肯定不会相交;
所以只需要在2中的(1)中去求h,但是下面的代码我化简了,避免精度出问题:
AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Node{
    
    
	ll x,y,R;
	Node(ll RR=0){
    
    R=RR;}
	Node(ll xx,ll yy){
    
    
		x=xx;y=yy;
	}
	Node operator-(Node a){
    
    
		return Node(x-a.x,y-a.y);
	}
	ll operator^(Node b){
    
    
	    return 	x*b.y-b.x*y;
	}
	ll operator*(Node b){
    
    
		return x*b.x+y*b.y;
	}
}p[60],line[60];
ll book[60];
ll Dis(Node a,Node b){
    
    //两点间的距离的平方 
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 
}
bool judge(Node a,Node b,Node c){
    
    //判断是否有点在圆内或者边上 
	return Dis(a,b)<=a.R*a.R||Dis(a,c)<=a.R*a.R;
}
bool Jud_dis(Node a,Node b,Node c){
    
    
	Node ab=b-a;
	Node ac=c-a;
	ll val=(ab^ac);
	ll Diss=Dis(b,c);
	Node ba=a-b;
	Node bc=c-b;
	ll t=ba*bc;
	Node ca=a-c;
	Node cb=b-c;
	ll t2=ca*cb;
	if(t>=0&&t2>=0)
	return val*val<=a.R*a.R*Diss;//判断是否和圆相交 
	else return false;
}
int main(){
    
    
 ll T;
  scanf("%lld",&T);
  ll g=1;
  while(T--){
    
    
  	 ll c,pp;
  	 for(ll i=0;i<60;i++)book[i]=0;
  	 scanf("%lld %lld",&c,&pp);
  	 for(ll i=0;i<c;i++){
    
    
  	 	   scanf("%lld %lld %lld",&p[i].x,&p[i].y,&p[i].R);
	   }
	  for(ll i=0;i<pp;i++){
    
    
		  scanf("%lld %lld",&line[i].x,&line[i].y); 
     	}
     	for(ll i=0;i<c;i++){
    
    
     	   for(ll j=0;j<pp-1;j++){
    
    
     	    	    if(judge(p[i],line[j],line[j+1])){
    
    //判断是否有点再圆上或者圆内 
     	    	    	book[i]=1;
     	    	    	//cout<<j<<":"<<j+1<<endl;
					 }else if(Jud_dis(p[i],line[j],line[j+1])){
    
    //判断在都是<=90度的情况下h和dis的关系 
					 //cout<<j<<":"<<j+1<<endl;
					 	book[i]=1;
					 }
		    }
	    }
     	int f=0;
     	for(ll i=0;i<c;i++){
    
    
     		  if(book[i]){
    
    
     		  	  f=1;break;
			   }
		 }
		 if(f){
    
    
		 	printf("Compound #%lld: Reptile triggered these cameras: ",g++);
		 	for(ll i=0;i<c;i++){
    
    
		 		  if(book[i])printf("%lld%c",i+1,i==c-1?'\n':' ');
			 }
			 puts("");
		 }else{
    
    
		 		printf("Compound #%lld: Rigid Reptile was undetected\n\n",g++);
		 }
  }
//for(int i=0;i<50;i++){
    
    
//  cout<<rand()<<" "<<rand()<<endl;
//  cout<<rand()<<" "<<rand()<<endl; 
//}
	return 0;
}

猜你喜欢

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