文章目录
- 求阶乘
- 双子数
求阶乘
求阶乘
分析k的范围,10的18次方。这个数字很大
想要末尾有0的存在必须要2和5,但是通过分析2的数目应该是远远多于5的,所以只要5的数目够多即可。所以for循环的层次也是10的九次方以上,必然会超时,想到了用二分法来解决。
如何计算N的阶乘包含多少个5呢?
public static long solve(long n){
// 25阶乘进来 6个 30 5 10 15 20 25(2) 30 七个5
long res=0;
while (n>0){
res+=n/5; //res+=n/5 如果是5的n次方倍数,需要考虑;
n/=5;
}
return res;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
long n=scanner.nextLong();
//用数组存起来
long l=1,r=Long.MAX_VALUE;
while (l<r){
long mid=l+(r-l>>1);
if (solve(mid)<n) l=mid+1;
else r=mid;
}
//多少个零
long result=solve(l);
if (result==n) System.out.println(l);
else System.out.println(-1);
}
public static long solve(long n){
// 25阶乘进来 6个 30 5 10 15 20 25(2) 30 七个5
long res=0;
while (n>0){
res+=n/5;
n/=5;
}
return res;
}
}
双子数
线性筛实现。
#include <bits/stdc++.h>
#define int __int128 //用__int128稳一点
using namespace std;
long long ans=0;
const int n=10000010;
bool f[10000010]={1,1}; //标记
vector<int> v;
signed main(){
for(int i=2;i<=n;i++)
{
if(f[i]!=1)
v.push_back(i);
for(int j=0;j<v.size()&&v[j]*i<=n;j++)
{
f[v[j]*i]=1;
if(i%v[j]==0)break;
}
}
for(int i=0;i<v.size();i++)
for(int j=i+1;j<v.size();j++)
{
if(v[i]*v[i]*v[j]*v[j]<2333)continue;
else if(v[i]*v[i]*v[j]*v[j]>23333333333333)break;
ans++;
}
cout<<ans<<endl;
}