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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值