• 洛谷 7月月赛 Div.2 T1 可持久化动态仙人掌的直径问题


    题目背景

    众所周知,一场考试需要一道签到题。

    题目描述

    给定 n , m,求有多少个正整数 x,使得 xm ≤ n

    输入格式

    一行两个正整数  m。

    输出格式

    一个整数表示正整数 x 的个数。

    输入输出样例

    输入 #1
    5 2
    输出 #1
     2

    说明/提示

    对于 25\%25% 的数据满足 m = 1

    对于 50\%50% 的数据满足 ≤ 106

    对于100\%100%的数据满足 n , m ≤ 109


    这是昨天洛谷月赛Div.2的T1
    确实非常签到(但就是花了好大功夫才做出来,淦)
    看到题目首先联想到的是快速幂
    很快就否定了这种解法(其实我根本没想用快速幂)
    看到这个 x≤ n又准备用cmath库的log函数做个换底来减少枚举量
    但是花了将近四十五分钟以后以失败告终(谁知道这是个纯暴力呢)
    于是准备打个m == 1 的表(前25%)然后暴力枚举
    于是有了以下代码
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <cstdlib>
    #include <set>
    
    using namespace std;
    
    long long n, m;
    long long x;
    long long cnt = 0;
    
    inline long long read()
    {
        long long x = 0;
        long long w = 1;
        char c = getchar();
        while(c < '0' || c > '9')
        {
            if(c == '-')
              w = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + c - '0';
            c = getchar();
        }
        return x * w * 1ll;
    }
    
    int main()
    {
        n = read();
        m = read();
        if(m == 1)
          printf("%lld", n);
        if(m > n)
          printf("1");
        if(m == 2)
        {
            for(int i = 1; i <= sqrt(n) ; i++)
            {
              if(pow(i , 2) <= n)
                cnt++;
            }
        cout<<cnt;
        }
        if(m == 4)
        {
            for(int i = 1; i <= (sqrt(n)); i++)
            {
                if(pow(i , m) <= n)
                  cnt++;
            }
            cout<<cnt;
        }
        if(m != 2 && m != 4){
          for(int i = 1; i <= sqrt(n); i++)
          {
              if(pow(i , m) <= n)
                cnt++;
            cout<<cnt;
          }    
        }
        /*
        double ans;
        //  log(n)/m == log(x);
        double need = log(n) / m;
        for(int i = 1; i <= 1e6; i++)
        {
            ans = log(i);
            if(ans == need)
            {
                cout<<i;
                return 0;
            }
        }
        cout<<"No answer";
        */
    }
    结果它就SPFA了...

    我们来想想为啥
    是数组开小了么——会RE
    是递归次数不够么——扯
    好像是这一段不大对
        if(m > n)
          printf("1");
    于是在一脸懵逼中我把代码改成了下面这样
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <cstdlib>
    #include <set>
    
    using namespace std;
    
    long long n, m;
    long long x;
    long long cnt = 0;
    
    inline long long read()
    {
        long long x = 0;
        long long w = 1;
        char c = getchar();
        while(c < '0' || c > '9')
        {
            if(c == '-')
              w = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + c - '0';
            c = getchar();
        }
        return x * w * 1ll;
    }
    
    int main()
    {
        n = read();
        m = read();
        if(m == 1)
          printf("%lld", n - 1);
        if(m == 2)
        {
            for(int i = 1; i <= sqrt(n) ; i++)
            {
              if(pow(i , 2) <= n)
                cnt++;
            }
        cout<<cnt;
        }
        if(m == 4)
        {
            for(int i = 1; i <= (sqrt(n)); i++)
            {
                if(pow(i , m) <= n)
                  cnt++;
            }
            cout<<cnt;
        }
        if(m != 2 && m != 4)
        {
          for(int i = 1; i <= sqrt(sqrt(n)); i++)
          {
              if(pow(i , m) <= n)
                cnt++;
          }
        cout<<cnt;
        }
        /*
        double ans;
        //  log(n)/m == log(x);
        double need = log(n) / m;
        for(int i = 1; i <= 1e6; i++)
        {
            ans = log(i);
            if(ans == need)
            {
                cout<<i;
                return 0;
            }
        }
        cout<<"No answer";
        */
    }
    用导数的思想对递归进行一些优化
    于是我又交了一遍...

    ?
    我直接疑天下之大惑
    为啥会WA一个点?
    ???
    于是开始一点点地排查
    最后发现...
    if(m == 1)
          printf("%lld", n);
    就不该写,导致跟后面(m != 2 && m != 4)判重了...
    本来想骗的25居然没拿到...

    改成这样就行辣(我也不知道109数据枚举咋过去的反正我就是过去了)
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <cstdlib>
    #include <set>
    
    using namespace std;
    
    long long n, m;
    long long x;
    long long cnt = 0;
    
    inline long long read()
    {
        long long x = 0;
        long long w = 1;
        char c = getchar();
        while(c < '0' || c > '9')
        {
            if(c == '-')
              w = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + c - '0';
            c = getchar();
        }
        return x * w * 1ll;
    }
    
    int main()
    {
        n = read();
        m = read();
        if(m == 1)
          printf("%d", n);
        if(m == 2)
        {
            for(int i = 1; i <= sqrt(n) ; i++)
            {
              if(pow(i , 2) <= n)
                cnt++;
            }
        cout<<cnt;
        }
        if(m == 4)
        {
            for(int i = 1; i <= (sqrt(n)); i++)
            {
                if(pow(i , m) <= n)
                  cnt++;
            }
            cout<<cnt;
        }
        if(m != 2 && m != 4 && m != 1)
        {
          for(int i = 1; i <= sqrt(sqrt(n)); i++)
          {
              if(pow(i , m) <= n)
                cnt++;
          }
        cout<<cnt;
        }
        /*
        double ans;
        //  log(n)/m == log(x);
        double need = log(n) / m;
        for(int i = 1; i <= 1e6; i++)
        {
            ans = log(i);
            if(ans == need)
            {
                cout<<i;
                return 0;
            }
        }
        cout<<"No answer";
        */
    }
  • 相关阅读:
    WslRegisterDistribution failed with error: 0x80370102
    vscode C/C++ 语法检查
    ADO.NET 一(概述)
    线程三(Mutex)
    线程二(Monitor)
    线程一(lock)
    interface Part4(接口中的多态)
    interface Part3(实现:显示和隐式)
    interface Part2(定义接口)
    interface Part1(接口详解)
  • 原文地址:https://www.cnblogs.com/Jiangxingchen/p/13379176.html
Copyright © 2020-2023  润新知