Dytechlab Cup 2022B. Ela's Fitness and the Luxury Number(卡sqrt精度 二分)

111 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。
B. Ela's Fitness and the Luxury Number
题目

image.png 题目分析

其实这题很简单只要我们手动写几个数据就可以发现进行对于数据x 只有xx x(x+1) (x+1)(x+1)只有x*x\ x*(x+1)\ (x+1)*(x+1)三个数字开根号向下取整过后能被x整除所以我i们只需要判断一下l和r的位置即可

所以就有了第一份代码

void solve()
{
   int l,r; cin >> l >> r;
   int L = floor(sqrt(l));
   int R = floor(sqrt(r));
   auto checkl = [&](int x) {
      int y = floor(sqrt(x));
      int R = (y + 1) * (y + 1) - 1;
      int L = y * y;
      if(x <= L) return 3ll;
      else if(x <= y * ( y + 1)) return 2ll;
      else return 1ll;
   };
   auto checkr = [&](int x) {
      int y = floor(sqrt(x));
      int R = (y + 1) * (y + 1) - 1;
      int L = y * y;
      if(x >= R) return 3ll;
      else if(x >= y * ( y + 1)) return 2ll;
      else return 1ll;
   };
   int res = (R - L - 1) * 3ll;
   res += checkl(l) + checkr(r);
   cout << res << endl;
}

image.png提交过后我们会发现wa2了再经过长达十分钟的自我hack过后发现我的思路应该是对的(确信)这时我看向的数据范围发现以double的精度范围好像是存储不下的所以double是不行的所以这时就想到哭了double的升级版long double.
long double也有对应的开根号返回函数sqrtl()这时我们将所有的ssqr改为sqrtl提交一次

image.png
发现就过了
但是如果你不知道这个函数的话你可以自己手写一个二分函数但是你需要调eps

image.png
在我将eps从1e-6调到了1e-10时终于过了
Code

const long double eps = 1e-10;
void solve()
{
   int l,r; cin >> l >> r;
   auto Sqrt = [&](int x) {
      long double l = 0,r = x;
      while(r - l > eps) {
        long double mid = (l + r) / 2;
        if(mid * mid >= x) r = mid;
            else l = mid;
      }
      return r;
   };
   int L = floor(Sqrt(l));
   int R = floor(Sqrt(r));
   auto checkl = [&](int x) {
      int y = floor(Sqrt(x));
      int R = (y + 1) * (y + 1) - 1;
      int L = y * y;
      if(x <= L) return 3ll;
      else if(x <= y * ( y + 1)) return 2ll;
      else return 1ll;
   };
   auto checkr = [&](int x) {
      int y = floor(Sqrt(x));
      int R = (y + 1) * (y + 1) - 1;
      int L = y * y;
      if(x >= R) return 3ll;
      else if(x >= y * ( y + 1)) return 2ll;
      else return 1ll;
   };
   int res = (R - L - 1) * 3ll;
   res += checkl(l) + checkr(r);
   cout << res << endl;
}

总结一下反正就是奇奇怪怪的错误很难受