本题是为了解决
自己测试的时候病没有发现问题,但是拿去dotcpp上就运行超时
#include<iostream>
#include<math.h>
#include <iomanip>
using namespace std;
int ling(unsigned long long int g);
int main()
{
unsigned long long int a;
cin>>a;
unsigned long long int num[28]={1,5,25,125,625,3125,15625,78125,390625,1953125,9765625,48828125,244140625,1220703125,6103515625,30517578125,152587890625, 762939453125, 3814697265625, 19073486328125, 95367431640625, 476837158203125, 2384185791015625, 11920928955078125, 59604644775390625, 298023223876953125, 1490116119384765625, 7450580596923828125};
int i=0;
while(a>=num[i])//求出目标区域,由于输入的是阶乘后面的0的个数,因此num[i]<5*n<num[i+1]
{
i++;
}
unsigned long long int l=num[i],r=num[i+1];//二分法求符合条件的最小值
while (l <= r)
{
unsigned long long int mid = floor((l + r) / 2);
unsigned long long int k=ling(mid);
if (a < k)
{
r = mid+1;
}
else if (a > k)
{
l = mid-1;
}
else
{
r=mid;
break;
}
}
//由于算法存在问题,所以要进一步缩小目标值
unsigned long long int o=ling(r),t;
t=o;
if(o!=a)
{
cout<<"-1"<<endl;
}
else
{
while(o==t)
{
t=ling(r);
r--;
}
r+=2;
cout<<setprecision(20)<<r<<endl;
}
return 0;
}
int ling(unsigned long long g)//求多少个0
{
unsigned long long a=0;
while(g)
{
a += floor(g/5);
g = floor(g/5);
}
return a;
}
数学规律,,数5的个数,,,一个5的范围一个5,一个25的范围6个5,一个125的范围25个5,,以此类推。
然后倒着算大范围+小范围,就可以了
改成String试试