Yet Another Problem About Pi(數學問題)
阿新 • • 發佈:2021-08-13
Yet Another Problem About Pi
題意:
平面上有無窮個長,寬為w,d的矩形方格。你有一條長度為Π的曲線可以任意彎折,起點任意,求曲線最多經過的方格數目(不計邊界)
思路:
先考慮最壞情況:對應max(w,d)>PI時,我們不能越過任何一個方格,此時我們的最佳方案應該是以四個矩形方格的交點為起點,向周圍走一圈,最小結果為4
- 如果我們能夠越過方格,我們可以認為以下的所有情況都是有上方(結果為4)的情況推廣而來,因為上述拿法是開局最佳。並且因為是無限迴圈小數,我們可以認為折線極其微小,但是真實存在,此時可以忽略折線的長度,我們有兩種方案:
- 走直線:取,走長度更小的一側必然更優,此時每越過一個格子增加貢獻為2
- 走曲線:取,每越過一個格子增加貢獻為3(即斜對角方格和其旁邊緊挨兩格)
- 走直線:取,走長度更小的一側必然更優,此時每越過一個格子增加貢獻為2
- 可見的是,我們要協調上述兩種操作,使得最後的貢獻最多。並且可以知道的是:在使用上述操作時,僅有邊界情況會影響操作的選擇是否需要改變(如走直線變成走曲線)。所以這種變換操作最多存在兩次(可以類比回退一步求更優值),所以直接列舉上述兩種操作的存在次數,對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; }