NC22751. 小西小理的计算几何
描述
输入描述
输入第一行包括一个整数T,代表测试数据组数(1 <= T <= 10000)
接下来T组数据,每组数据用4行表示
第一行包括三个整数x,y,r,分别代表圆的圆心与半径(-3000 <= x, y <= 3000, 1 <= r <= 3000)
接下来三行每行包括两个整数a,b,表示三角形的一个顶点(-3000 <= a, b <= 3000)
输出描述
共T行,对于每组输入数据,如果三角形和圆相交输出"Yes",否则输出"No",每组输出占一行。
示例1
输入:
2 2 2 1 0 0 1 0 0 1 2 2 1 0 0 2 0 2 2
输出:
No Yes
C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 456K, 提交时间: 2019-03-10 12:13:41
#include <iostream> #include <algorithm> #include <vector> #include <stdio.h> #include <string> using namespace std; #define N 100 #define cheng(a,b,c,d) ((a-b)*(a-b)+(c-d)*(c-d)) int r; long long calc(int x1,int y1,int x2,int y2,int x,int y) { long long temp=abs((x1-x2)*y-(y1-y2)*x+((y1-y2)*x1-y1*(x1-x2))); temp*=temp; long long tmp=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); long long point=(x-x1)*(x2-x1)+(y-y1)*(y2-y1); long long point1=(x-x2)*(x1-x2)+(y-y2)*(y1-y2); return temp-tmp*r<=0 && point>=0 && point1>=0; } int main() { int t=0; scanf("%d",&t); while(t--) { int x,y; scanf("%d %d %d",&x,&y,&r); int a1,b1,a2,b2,a3,b3,flag1=0,flag2=0,flag3=0; scanf("%d %d %d %d %d %d",&a1,&b1,&a2,&b2,&a3,&b3); int a,b,c; a=cheng(a1,x,b1,y); b=cheng(a2,x,b2,y); c=cheng(a3,x,b3,y); r=r*r; if(a<r && b<r && c<r) printf("No\n"); else if(a>r && b>r &&c>r) { if(calc(a1,b1,a2,b2,x,y)) flag1=1; if(calc(a3,b3,a2,b2,x,y)) flag2=1; if(calc(a1,b1,a3,b3,x,y)) flag3=1; if(flag1==0 && flag2==0 && flag3==0) printf("No\n"); else { printf("Yes\n"); } } else printf("Yes\n"); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 500K, 提交时间: 2020-03-17 14:32:00
#include<bits/stdc++.h> using namespace std; int x,y,r; int a[4],b[4]; float length[3]; bool hhh(int x1,int y1) { if(1.0*(x-x1)*(x-x1)+1.0*(y-y1)*(y-y1)-r*r<=0) return 1; else return 0; } bool judge(int x1,int y1,int x2,int y2) { if(hhh(x1,y1)&&hhh(x2,y2)) return false; if(!hhh(x1,y1)&&hhh(x2,y2)||hhh(x1,y1)&&!hhh(x2,y2)) return true; double A,B,C; if(x1==x2) A=1,B=0,C=-x1; else if(y1==y2) A=0,B=1,C=-y1; else { A=y1-y2; B=x2-x1; C=x1*y2-y1*x2; } if((A*x+B*y+C)*(A*x+B*y+C)/(A*A+B*B)>r*r) return false; if((x-x1)*(x2-x1)+(y-y1)*(y2-y1)>0&&(x-x2)*(x1-x2)+(y-y2)*(y1-y2)>0) return true; return false; } int main() { int n; cin>>n; while(n--) { cin>>x>>y>>r; int flag=0; for(int i=0;i<3;i++) { cin>>a[i]>>b[i]; } a[3]=a[0]; b[3]=b[0]; double D[3]; for(int i=0;i<3;i++) { if(hhh(a[i],b[i])) flag++; } if(flag==3||!judge(a[0],b[0],a[1],b[1])&&!judge(a[1],b[1],a[2],b[2])&&!judge(a[0],b[0],a[2],b[2])) cout<<"No"<<endl; else cout<<"Yes"<<endl; } }