牛客多校8.K.Yet Another Problem About Pi 计算几何/思维

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客多校8.K.Yet Another Problem About Pi 计算几何/思维相关的知识,希望对你有一定的参考价值。


Problem Analysis

题目大意转述:给你一个无限延伸的网格的长和宽,现在有一条固定长度的绳子(长为),绳子可以摆成任意形状,求放到网格上去最多能经过的网格数目。

首先要确定绳子怎么摆才能达到这个目的:我们要经过近可能多的点,那么要经过尽可能多的顶点,而经过定点分为两种情况:

牛客多校8.K.Yet

在左侧的情况中,经过上面的点时,利用绳子无限小数部分向四个格子延展出一点点,可以使绳子穿过四个格子;而竖着向下走,再统计下一个点的情况时,我们可以发现途中蓝色阴影部分的两个格子是被重复统计的

在右侧的情况中,同样经过两个点,我们发现被重复统计的点只有一个。但是相比于第一种走法,它需要耗费更长的长度。

那么为了保证同一长度能够覆盖尽可能多的格子,我们有两种可供选择的方案:我们先举一个例子

牛客多校8.K.Yet

很显然,在这个例子中全直着走,全斜着走能覆盖的方格数目均不是最多的,直着走会因为重复统计而使产生过多无意义贡献;斜着走会因为长度限制而无法到达第三个点,从而导致放个覆盖数目减少。因此我们需要两者进行组合,那么就用两种方案

  1. 尽可能直着走,如果直着走到最后无法到达下一个点,考虑去除最后一个经过点改成斜着走
  2. 尽可能斜着走,①走到最后判断剩余的长度是否够一条直边,②去掉最后经过点改成直着走能否经过两个点

剩下的就是注意控制精度误差等等了。

AC Code

#include <bits/stdc++.h>
using namespace std;

const double pi = acos(-1);

inline int solve()
double x, y; cin >> x >> y;
double cro = sqrt(x * x + y * y);
if (x > y) x = y;
if (x > pi) return cout << "4" << endl, 0;
int ans = 4, xt = 0, ct = 0;
double xn = x / 2, crn = cro / 3;
if (xn < crn)
xt = int(pi / x);
ans += xt * 2;
if (pi - (xt - 1) * x > cro) ans++;

else
ct = int(pi / cro);
ans += ct * 3;
if (pi - ct * cro > x) ans += 2;
else if (pi - (ct - 1) * cro > 2 * x) ans++;

return cout << ans << endl, 0;


signed main()
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t; cin >> t;
while (t--) solve();
return 0;


以上是关于牛客多校8.K.Yet Another Problem About Pi 计算几何/思维的主要内容,如果未能解决你的问题,请参考以下文章

2019牛客多校第一场

2022 牛客多校 第四场 C

2022牛客多校2补题

2022牛客多校2补题

2022牛客多校2补题

2022牛客多校2补题