这道题。。。。。我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;
}