题目描述
今年乐乐开始学编程了,上几天刚刚解决了一个平方数的问题,问题是这样的:随便告诉你一个不超过 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;
}