Educational Codeforces Round 87(Div. 2 등급) C2.Not So Simple Polygon Embedding

나는 너무 빠르지는 않지만 이해하기 쉬운 코드를 작성했습니다:
그것은 대략 이분법적입니다(여기서 이분법은 O(1)이어야 합니다).
먼저 전체 2n 다각형 면의 특정 정점을 보자(1,0). 중앙에 구성된 사각형 at (0,0) 이 경우는 분명히 가장 작지 않습니다. 또한 우리는 가장 작은 정사각형을 만들기 위해 원점을 중심으로 각도를 회전시키기만 하면 된다는 것을 알 수 있습니다: 그림을 그리고 회전 각도가 π 4 n \frac{\pi}{4n}4
그런 다음 C1 코드의 경우 이분법 함수에서 지금 각도를 변경하십시오.

const int N=200010,M=N*2,mod=1e9+7;
int n,m,k,a[N];
string p;
double angle;

bool check(double w){
    
    
	w/=2.0;
	double tmp=(PI-angle)/2.0;
	double r=sin(tmp)/sin(angle);
	// debug(r);
	double now=PI/(4.0*n);
	bool ok=true;
	for(int i=0;i<n*2;++i){
    
    
		double x=r*cos(now),y=r*sin(now);
		if(sign(x-w)>0||sign(x+w)<0||sign(y-w)>0||sign(y+w)<0) {
    
    
			ok=false;
			break;
		}
		now += angle;
	}
	if(ok) return ok;
	now=0;ok=true;
	for(int i=0;i<n*2;++i){
    
    
		double x=r*cos(now),y=r*sin(now);
		if(sign(x-w)>0||sign(x+w)<0||sign(y-w)>0||sign(y+w)<0) {
    
    
			return false;
		}
		now += angle;
	}
	return true;
}

void solve(){
    
    
	double one=PI/180.0;
	scanf("%d",&n);	
	angle=PI/n;
	double l=1,r=1e18;
	int cnt=200;
	while(cnt--){
    
    
		double mid=(l+r)/2.0;
		if(check(mid)) r=mid;
		else l=mid;
	}
	printf("%.10lf\n",l);
}

おすすめ

転載: blog.csdn.net/m0_51780913/article/details/127399611