洛谷春季ACM多校賽 Final Spark

題目描述

有一個長無限,寬爲 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章