UVA-10061 How many zero's and how many digits ? (数论)

题目大意:让求n!在base进制下的位数以及末尾0的连续个数。

题目分析:一个m位的b进制数N,最小是b^(m-1),最大不超过b^m,即b^(m-1)≤N<b^m。解不等式,得log10(N)/log10(b)<m≤log10(N)/log10(b)+1。

至于0的个数,要对n!分解质因数,对base分解质因数。看n!的质因数中能凑出多少个base。能凑出的base的个数就是末尾0的个数。设n!与base的共同质因数所构成的集合为s1。base的质因数构成的集合为s2,则末尾0的个数就是min(s1(s2(i))/s2(i))。

其实,这道题无非就是多个算法的整合。筛素数+筛大素数+分解质因数。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<map>
# include<cstring>
# include<algorithm>
using namespace std;
const int N=1<<20;
double a[N+50];
int pri[150],mark[800];
map<int,int>m[805];
void init()
{
    a[1]=log10(1.0);
    for(int i=2;i<=N;++i)
        a[i]=a[i-1]+log10(i);
    for(int i=2;i<=800;++i){
        int n=i;
        int a=2;
        while(a*a<=n){
            while(n%a==0){
                ++m[i][a];
                n/=a;
            }
            ++a;
        }
        if(n>1)
            ++m[i][n];
    }
    pri[0]=0;
    memset(mark,0,sizeof(mark));
    for(int i=2;i<=800;++i){
        if(!mark[i])
            pri[++pri[0]]=i;
        for(int j=1;j<=pri[0]&&i*pri[j]<=800;++j){
            mark[i*pri[j]]=1;
            if(i%pri[j]==0)
                break;
        }
    }
}
int f(int n,int k)
{
    map<int,int>mp;
    for(int i=2;i<=n;++i){
        int n=i;
        for(int j=1;j<=pri[0]&&pri[j]<=k;++j){
            while(n%pri[j]==0){
                ++mp[pri[j]];
                n/=pri[j];
            }
        }
    }
    map<int,int>::iterator it;
    int ans=1<<30;
    for(it=m[k].begin();it!=m[k].end();++it){
        ans=min(ans,mp[it->first]/(it->second));
    }
    return ans;
}
int g(int n,int k)
{
    double ans=a[n]/log10(k)+1.0;
    return (int)ans;
}
int main()
{
    init();
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        printf("%d %d\n",f(n,k),g(n,k));
    }
    return 0;
}

UVA-10061 How many zero's and how many digits ? (数论)

时间: 2024-10-06 02:34:16

UVA-10061 How many zero's and how many digits ? (数论)的相关文章

UVA 10061 How many zero&#39;s and how many digits ? (m进制,阶乘位数,阶乘后缀0)

题意:给出两个数字a和b,求a的阶乘转换成b进制后,输出(1)后缀中有多少个连续的0? (2)有多少位? 思路:逐个问题解决. 设a!=k.  k暂时不用直接转成b进制. (1)阶乘后缀0问题.先看这个十进制后缀0的例子:http://www.cnblogs.com/xcw0754/p/4604473.html 解法差不多,稍变化. 首先将b分解成若干质数(比如8={2*2*2})保存在一个集合A中(注意自然数的质数分解是唯一的),只要有一个序列A就能构成一个0,因为满b就进位,b可以表示成10

UVA - 10061 How many zero&#39;s and how many digits ?

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19099 给定一些点,求构成三角形最大面积,并且这个三角形不能不能包含其他点(在边上也不行). 因为数据范围很小,所以直接枚举就好,并且还把面积公式告诉了我们,判断点在三角形内的方法是,这个点与其他顶点的面积之和是否等于这个三角形的面积. #include<cstdio> #include<cmath> struct point { char z; int x,

UVA - 10061 How many zero&amp;#39;s and how many digits ?

n!=x*b^y, 当x为正整数时,最大的y就是n!末尾0的个数了, 把n,b分别拆成素因子相乘的形式: 比如, n=5,b=16 n=5,b=2^4, 非常明显,末尾0的个数为0 10进制时,n!=a*10^x b进制时,n!=c*b^y 非常明显,n!的位数就是最大的x+1 这里计算我用了log,精度设置为1e-9 #include<iostream> #include<cstdio> #include<vector> #include<cstring>

uva 10581 - Partitioning for fun and profit(记忆化搜索+数论)

题目链接:uva 10581 - Partitioning for fun and profit 题目大意:给定m,n,k,将m分解成n份,然后按照每份的个数排定字典序,并且划分时要求ai?1≤ai,然后输出字典序排在k位的划分方法. 解题思路:因为有ai?1≤ai的条件,所以先记忆化搜索处理出组合情况dp[i][j][s]表示第i位为j,并且剩余的未划分数为s的总数为dp[i][j][s],然后就是枚举每一位上的值,判断序列的位置即可. #include <cstdio> #include

uva 1341 - Different Digits(数论+bfs)

题目链接:uva 1341 - Different Digits 题目大意:给定一个数字n,要求求一个数字m,m可以整除n,并且尽量组成的数字种类(0~9)尽量少,在种类相同的情况下数值尽量小. 解题思路:可以证明两种数字肯定可以组成m,假设有数字k,一种数字可以有k,kk,kkk,kkkk,-整除n剩的数一定在0~n-1之间,所以肯定存在两个由k数字组成的数字同模,那么这两个数相减所得到的数即使kkk00000,两种数字.于是肯定了范围,枚举数字,然后用bfs获取答案,维护最小值即可. #in

uva 10061(数学)

题解:题目要在b进制下输出的是一个数字阶乘后有多少个零,然后输出一共有多少位.首先计算位数,log(n)/log(b) + 1就是n在b进制下有多少位,而log有个公式就是log(M×N) = logM + logN,n! 的位数用公式可以化为( log(1) + log(2) +...+log(n) ) / log(b) + 1,为了精确再加 10^-6.阶乘后的零的数量计算是根据进制数的最大质因数和其数量确定的,比如10 = 2 × 5,所以10进制的最大质因数是5,数量是num = 1,例

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

n!在k进制下的后缀0

问n! 转化成k进制后的位数和尾数的0的个数.[UVA 10061 How many zeros and how many digits?] Given a decimal integer number you will have to find out how many trailing zeros will be there in its factorial in a given number system and also you will have to find how many di

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te