题目描述
有一个长无限,宽为 w + t 的长方形,去切割一个半径为 S 的圆,问如何切割可以使得其切割所对应的弧最长,求其占据的比例,一共有T组测试数据
样例
3
20 20 20 1000
0 0 100 1000
100 100 198 2000
1.000000000
0.000000000
0.503215306
思路
1、如果 w+t >= 2*s ,那么是长方形是完全覆盖的,覆盖率为 1
2、如果 w+t==0,那么覆盖率为 0
3、根据page1, 想要求中间切割弧长的情况,我们可以通过切割圆的这个长度来计算,宽切割是一定的,长切割是会变化的,所以我们需要通过长来确定大小,就是求切割的两边长的最小值,长就是我图中红色描的线。我们把圆切开来分成两半只看正半轴情况,根据page2,求导(其实看看就看得出来),很容易发现越往边上移动切割长变化的速度是加快的,而越靠近中间的切割长的增速是很慢的。
我们就用上半圆来进行求解,请看我画的图,u1s1比较丑,不要介意
所以根据这个,我们就可得知,有一条边是与圆边上相切的。接下来的求解就简单了,角度除以360度,这边为了方便我只计算一半
然后分成两个小情况
我用画图的形式表示了
1、w + t >= s
2、w + t < s
太丑了,不要介意 233333333
注意点和思路讲完了,我就贴代码了
代码片
#include<bits/stdc++.h>
using namespace std;
double Abs(double x) {
return x>=0?x:-x;
}
void solve() {
double w,t,s,d;
scanf("%lf %lf %lf %lf",&w,&t,&s,&d);
if ( (w+t)/2.0>=s ) printf("1.000000000\n");
else if ( w+t==0 ) printf("0.000000000\n");
else if ( w+t>=s ) printf("%.9f\n",1.0 - acos(Abs(s-(w+t))/s) / acos(-1.0));
else printf("%.9f\n",acos(Abs(s-(w+t))/s) / acos(-1.0));
}
int main() {
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--) {
solve();
}
return 0;
}