L. Machining Disc Rotors
L. Machining Disc Rotors
题目求切割后圆上两点的最长距离,显然是圆边上的两点,n=100可以使用平方算法,对每个切割圆先判断是否外离内含,然后用余弦定理求出两交点与圆心连线的夹角,按顺时针标记为l,r,表示切割掉的弧,范围【0,2pi】,题目保证切割圆不会交叉,将弧按l排序,遍历求出留下来的弧,一个弧关于圆心的对称弧可以将l,r±pi来求得,最后n方判断对称弧是否与其他弧重叠(若重叠答案为直径),并求弧的左右端点和其他弧左右端点的距离,答案为最大值。
坑点是可能所有的切割圆都外离内含时容易挂掉,并且如果存在优弧则答案就是直径。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
struct P{
	double x,y;
}o1,o;
double l[110],r[110],ln[110],rn[110]; //[0.2pi) clockwise
double RR;
struct L{
	double l,r;
	bool operator <(L B)const{
		return l<B.l;
	}
}p[110],p2[110];
inline double cross(P A,P B,P C){
	return (A.x-C.x)*(B.y-C.y)-(B.x-C.x)*(A.y-C.y); //CA*CB
}
inline double dis(P A,P B){
	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
inline bool ck(double a,double b,double c){
	if(b>=a&&c>=a&&c<=b)return true;
	if(b<a&&(c<=b||c>=a))return true;
	return false;
}
double pi=acos(-1);
inline double f(double x){
	if(x>=pi)return x-pi;
	return x+pi; 
}
inline double xc(double a,double b){
	double r=fabs(a-b);
	if(r>pi)r=2*pi-r;
	return sqrt(2*RR*RR*(1-cos(r)));
}
int n;
inline bool check(int i){
	if(p[i].l==-1)return false;
	for(int j=1;j<=n;j++){
		if(j==i)continue;
		if(p[j].l==-1)continue;
		if(ck(p[j].l,p[j].r,p[i].l)&&ck(p[j].l,p[j].r,p[i].r))return false;
	}
	return true;
}
int main(){
    int T,TT;
    o1.x=1;
    scanf("%d",&T);TT=T;
    while(T--){
    	scanf("%d%lf",&n,&RR);
    	bool fl=false;
    	double ans=0;
    	for(int i=1;i<=n;i++){
    		double rr;
    		P t;
    		scanf("%lf%lf%lf",&t.x,&t.y,&rr);
    		double d=dis(t,o);
    		if(d>=rr+RR||(rr<RR&&d<=RR-rr)){
    			p[i].l=-1;
    			continue;
			}
    		double mid=acos(t.x/d);
    		if(t.y<0)mid=2*pi-mid;
    		double re=acos((-rr*rr+RR*RR+d*d)/(2*RR*d));
    		p[i].l=mid-re;
    		if(p[i].l<0)p[i].l+=2*pi;
    		p[i].r=mid+re;
    		if(p[i].r>=2*pi)p[i].r-=2*pi;
    	}
    	int pr,cnt=0,ct=0; 
    	for(int i=1;i<=n;i++){
    		if(check(i))p2[++ct]=p[i];
		}
		sort(p2+1,p2+ct+1);
		pr=ct;
    	for(int i=1;i<=ct;i++){
    		l[++cnt]=p2[pr].r;pr=i;
    		r[cnt]=p2[i].l;
    		ln[cnt]=f(l[cnt]);rn[cnt]=f(r[cnt]);
    		ans=max(xc(l[cnt],r[cnt]),ans);
    		double len=r[cnt]-l[cnt];
    		if(len<0)len+=2*pi;
    		if(len>=pi){
    			ans=2*RR;
    			break;
			}
    		for(int j=1;j<cnt;j++){
    			if(ck(l[j],r[j],ln[cnt])||ck(l[j],r[j],rn[cnt])
				||ck(ln[cnt],rn[cnt],l[j])||ck(ln[cnt],rn[cnt],r[j])){
    				fl=true;ans=2*RR;
    				break;
				}
				else {
					ans=max(xc(l[cnt],l[j]),ans);
					ans=max(xc(l[cnt],r[j]),ans);
					ans=max(xc(r[cnt],l[j]),ans);
					ans=max(xc(r[cnt],r[j]),ans);
				}
			}
			if(fl)break;
		}
		if(ans==0)ans=2*RR;
		printf("Case #%d: %.10f\n",TT-T,ans);
	}
	return 0;
}

相关文章:

  • 2022-12-23
  • 2021-11-03
  • 2021-09-01
  • 2022-12-23
  • 2021-06-27
  • 2022-12-23
  • 2022-01-03
猜你喜欢
  • 2022-01-21
  • 2021-11-21
  • 2021-08-20
  • 2021-10-15
  • 2021-12-24
  • 2022-01-14
  • 2021-05-07
相关资源
相似解决方案