立方(高精度乘法,二分)

题目描述
今年乐乐开始学编程了,上几天刚刚解决了一个平方数的问题,问题是这样的:随便告诉你一个不超过 1 个亿的正整数,请你算出不超过该数的所有立方数的个数。
但是,如果这个超过 1 亿,是一个 18 位正整数,或 28 位的正整数呢?
乐乐不会算,你会吗?

输入
只有一行且只有一个正整数:n

输出
只有一行且只有一个正整数:不超过 n 的平方数个数

样例输入
100

样例输出
4

提示
111 = 1 222 = 8
333 = 27 444 = 64
555 = 125 但是 125 > 100

对于 30%的数据, 1 <= n <= 10^8
对于 70%的数据, 1 <= n <= 10^18
对于 100%的数据, 1 <= n <= 10^28

思路

看一下数据范围 10^18以内 long long 可以存
直接暴力

10^18 到 10^28 高精度乘法暴力会超时
可以考虑用二分(模板二)找到答案

AC代码

#include<iostream>
#include<vector>
 
using namespace std;
 
vector<int> tmp,num;
 
vector<int> mul(vector<int> &A,long long &B)
{
    vector<int> C;
    long long t = 0;
    for(int i = 0; i < A.size() || t; i++)
    {
        if(i < A.size()) t += A[i]*B;
        C.push_back(t%10);
        t /= 10;
    }
 
    while(C.size() > 0 && C.back() == 0) C.pop_back();
    A.clear();
 
    return C;
}
 
bool check(long long mid)
{
    long long t = mid;
    tmp.clear();
    while(t != 0)
    {
        tmp.push_back(t%10);
        t /= 10;
    }
    tmp = mul(tmp,mid);
    tmp = mul(tmp,mid);
 
    int sign = 1;
    if(tmp.size() > num.size())
    {
        return 1;
    }
    else if(tmp.size() < num.size())
    {
        return 0;
    }
    else if(tmp.size() == num.size())
    {
        int i = tmp.size() - 1;
        while(i >= 0)
        {
            if(tmp[i] == num[i])
            {
                i--;
                continue;
            }
            else if(tmp[i] > num[i])
            {
                break;
            }
            else
            {
                sign = 0;
                break;
            }
        }
        if(i == -1) sign = 0;
    }
    if(sign) return 1;
    else return 0;
 
 
}
 
void find(long long l,long long r)
{
    while(l < r)
    {
        long long mid = l + r>> 1;
        if(check(mid))
        {
            r = mid;
        }
        else
        {
            l = mid + 1;
        }
    }
    cout << l-1 << endl;
}
 
int main()
{
    string n;
    cin >> n;
    if(n.size() <= 8)
    {
        long long t = 0;
        long long i = 0;
        while(i < n.size())
        {
            t += n[i]-'0';
            t *= 10;
            i++;
        }
        t/= 10;
        for(i = 1000;;i--)
        {
            if(i*i*i < t) break;
        }
        cout << i << endl;
    }
    else if(n.size() <= 18)
    {
        long long t = 0;
        long long i = 0;
        while(i < n.size())
        {
            t += n[i]-'0';
            t *= 10;
            i++;
        }
        t/= 10;
        for(i = 1000000;;i--)
        {
            if(i*i*i < t) break;
        }
        cout << i << endl;
    }
    else
    {
        long long i;
        for(i = n.size()-1; i >=0; i--)
        {
            num.push_back(n[i]-'0');
        }
        find(1e6,1e10);
 
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值