1. 程式人生 > 其它 >Yet Another Problem About Pi(數學問題)

Yet Another Problem About Pi(數學問題)

Yet Another Problem About Pi

題意:

​ 平面上有無窮個長,寬為w,d的矩形方格。你有一條長度為Π的曲線可以任意彎折,起點任意,求曲線最多經過的方格數目(不計邊界)

思路:

​ 先考慮最壞情況:對應max(w,d)>PI時,我們不能越過任何一個方格,此時我們的最佳方案應該是以四個矩形方格的交點為起點,向周圍走一圈,最小結果為4

  • 如果我們能夠越過方格,我們可以認為以下的所有情況都是有上方(結果為4)的情況推廣而來,因為上述拿法是開局最佳。並且因為是無限迴圈小數,我們可以認為折線極其微小,但是真實存在,此時可以忽略折線的長度,我們有兩種方案:
    • 走直線:取,走長度更小的一側必然更優,此時每越過一個格子增加貢獻為2
    • 走曲線:取,每越過一個格子增加貢獻為3(即斜對角方格和其旁邊緊挨兩格)
  • 可見的是,我們要協調上述兩種操作,使得最後的貢獻最多。並且可以知道的是:在使用上述操作時,僅有邊界情況會影響操作的選擇是否需要改變(如走直線變成走曲線)。所以這種變換操作最多存在兩次(可以類比回退一步求更優值),所以直接列舉上述兩種操作的存在次數,對res取最大值即可

程式碼:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const double PI = acos(-1);
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t;
    cin>>t;
    while(t--){
    	double n,m;
    	cin>>n>>m;
    	int res=0;
    	double xie=sqrt(n*n+m*m);
    	double mi=min(n,m);
    	for(int i=0;i<3;i++){
    		if(i*mi<=PI){
    			res=max(res,(int)(4+i*2+floor((PI-i*mi)/xie)*3));
			}
    		if(i*xie<=PI){
    			res=max(res,(int)(4+i*3+floor((PI-i*xie)/mi)*2));
			}
		}
		cout<<res<<endl;
	}
    return 0;
}