洛谷 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";
    */
}

猜你喜欢

转载自www.cnblogs.com/Jiangxingchen/p/13379176.html
今日推荐