2021 牛客暑期多校第8场 -K Yet Another Problem About Pi

Yet Another Problem About Pi

其实这道题对自己来说可以说难,说简单也可,题解的思路并不难,但是自己比赛中能不能想到这是一个重点。


在以上情况基础上,再往下发展,首先PI是无穷小数,围绕四个方格中心的消耗我们可以忽略不计,再分成两种情况

  1. 往对角线走 贡献+3
  2. 沿着短的那条边走 贡献+2
    直接暴力分两种情况记录答案即可
#include<bits/stdc++.h>
#include<unordered_map>
#define INF 0x7f7f7f7f
const int maxn=1e5+7;
#define ll long long
#define dbg(x) cout << #x << " = " << x << endl;
const double eps=1e-7;
using namespace std;
const ll mod=1e9+7;
double PI = acos(-1.0);
int n;
double w, d;
ll check(ll x, double len)
{
    ll ans = 4;//初始4个格子
    ans += x * 3;//对角线的贡献
    double f = PI - x * len;//剩余的线的长度
    ll k = f / min(w, d);
    ans += k * 2;//贡献
    if (k == 0 && x * len == PI)//没有横线只有对角线且刚刚好,那么少3个贡献
        ans -= 3;
    else if (k && (x * len + k * min(w, d)) == PI)//有横线少2个
        ans -= 2;
    return ans;
}
int main()
{
    cin >> n;
    while(n--){
        scanf("%lf%lf", &w, &d);
        double len = sqrt(w * w + d * d);//对角线长度
        /*ll l = 0, r = PI / len;//最多画多少个对角线
        while(l + 5 < r)
        {
 
            ll k = (r - l);
            ll mid1 = l + k / 3;
            ll mid2 = l + k * 2 / 3;
            if (check(mid1, len) < check(mid2, len))
                l = mid1;
            else
                r = mid2;
        }
        */
        ll num = PI / len;
        ll ans = 0;                                     //这里是为了防止超时的处理
        for (ll i = 0; i <= min(num, (ll)50); i++)      
            ans = max(ans, check(i, len));
 
        for (ll i = max((ll)0, num - 50); i <= num; i++)
            ans = max(ans, check(i, len));
 
        printf("%lld\n", ans);
    }
    return 0;
 
}
posted @ 2021-08-09 21:59  DurKui  阅读(67)  评论(0)    收藏  举报