나는 너무 빠르지는 않지만 이해하기 쉬운 코드를 작성했습니다:
그것은 대략 이분법적입니다(여기서 이분법은 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);
}