题意是求 n 的阶乘的位数。

直接求 n 的阶乘再求其位数是不行的,开始时思路很扯淡,想直接用一个数组存每个数阶乘的位数,用变量 tmp 去存 n 与 n - 1 的阶乘的最高位的数的乘积,那么 n 的阶乘的位数就等于 n - 1 的阶乘的位数加 tmp 的位数再减去 1。

但这种做法是不对的,例如有可能最高位与 n 的乘积结果是 99,而其实 n 与其他位的乘积结果是能进到这一位的,也就是说实际应该在 n - 1 的阶乘位数上增加 2 ( 3 -1 ) 位。而在对样例测试时也发现 n 为 10 的时候结果尚正确,但当 n 为 20 的时候就比正确结果少了 1,也就是说发生了上述情况。

抱着侥幸心理,又再次将每次乘以最高位的做法调整成了每次乘以最高的两位,这一次当 n 为 20 时结果依然正确,但是内存超了......

错误代码:

 #include <bits/stdc++.h>
using namespace std;
int tmp,dig[];
int getdigit(int n)
{
int a();
while(n)
{
n/=;
a++;
}
return a;
}
void make()
{
int digit;
dig[] = ;
dig[] = ;
dig[] = ;
dig[] = ;
tmp = ;
for(int i = ; i <= ; i++)
{
tmp *= i;
digit = getdigit(tmp);
dig[i] = digit + dig[i-] - ;
for(int j = ; j < digit; j++) tmp/=;
}
}
int main()
{
int t,ans,n;
scanf("%d",&t);
make();
while(t--)
{
scanf("%d",&n);
printf("%d\n",dig[n]);
}
return ;
}

在借鉴了其他人的做法后,才觉得对这道题有了一点正确的思路:

首先,一个数 x 的位数可以用以 10 为底取对数再向上取整的方法求得,即 digit( x ) = ceil ( log10( x ) );

那么,阶乘的位数可以直接求:digit( n! ) = ∑ log10( i ) ( i 从 1 取到 n )

代码如下:

 #include <bits/stdc++.h>
using namespace std;
int main()
{
int t,n;
double ans;
scanf("%d",&t);
while(t--)
{
ans = ;
scanf("%d",&n);
for(int i = ; i <= n; i++)
{
ans += log10(i);
}
printf("%d\n",(int)ans+);
}
return ;
}

另外,在求 n 的阶乘的时候用 Stirling 公式 也是很好的做法,

代码如下:

 #include <bits/stdc++.h>
using namespace std;
const double pi = acos(-);
int main()
{
int t,n,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ans = ceil((log(n)*n - n + 0.5*log(*pi*n) )/ log());
printf("%d\n",ans);
}
return ;
}

HDU 1018(阶乘位数 数学)的更多相关文章

  1. HDU 1018 阶乘数的位数

    题目大意: 将一个数开阶乘后得到的值,来求这个值的位数 n! = 1*2*3*4...*n 对于求一个数的位数的方法为ans = lg(n!) + 1 那么就可以看作 ans = lg(1) + lg ...

  2. HDU 1018 Big Number 数学题解

    Problem Description In many applications very large integers numbers are required. Some of these app ...

  3. hdu 1018 Big Number 数学结论

    Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  4. 【HDOJ1018】【大数阶乘位数】【斯特林公式】

    http://acm.hdu.edu.cn/showproblem.php?pid=1018 Big Number Time Limit: 2000/1000 MS (Java/Others)     ...

  5. HDU 1018 Big Number

    LINK:HDU 1018 题意:求n!的位数~ 由于n!最后得到的数是十进制,故对于一个十进制数,求其位数可以对该数取其10的对数,最后再加1~ 易知:n!=n*(n-1)*(n-2)*...... ...

  6. Java实现第九届蓝桥杯阶乘位数

    阶乘位数 题目描述 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞&qu ...

  7. java实现第七届蓝桥杯阶乘位数

    阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计算,9999 的阶乘的二进制表示一共有多少位? 注意:需要提交的是 ...

  8. java实现第四届蓝桥杯阶乘位数

    阶乘位数 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格 ...

  9. HDU 1018 Big Number (阶乘位数)

    题意: 给一个数n,返回该数的阶乘结果是一个多少位(十进制位)的整数. 思路: 用对数log来实现. 举个例子 一个三位数n 满足102 <= n < 103: 那么它的位数w 满足 w ...

随机推荐

  1. 在ubuntu上安装运行ionic项目

    1.安装nodejs.npm curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install - ...

  2. MT【262】一道常见错题

    若$f(x^2)$的定义域为$[-1,1]$,则函数$f(x)$的定义域为______ 设$a>0$构造$f(x)=\sqrt{x(1-x)(a+x)}$,此时$f(x^2)$的定义域为$[-1 ...

  3. IDEA+Springboot+JRebel热部署实现

    步骤一:在IDEA中安装JRebel插件(File->settings->plugins->search in repositories),如下图 步骤二:安装完成之后,重启idea ...

  4. 如何在代码中减少if else语句的使用

    前言 代码中嵌套的if/else结构往往导致代码不美观,也不易于理解.面向过程的开发中代码有大量的if else,在java中可以用一些设计模式替换掉这些逻辑,那么在js中是否也有类似的方法用来尽可能 ...

  5. javascript Object的新方法

    今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下: 前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列i ...

  6. B1018. 锤子剪刀布

    大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入格式: 输入第1行给出正整数N( ...

  7. Flask block继承和include包含

    继承(Block)的本质是代码替换,继承我认为就是把完整的html文件继承到一个不完整的html文件里. 被继承html文件: <!DOCTYPE html> <html lang= ...

  8. bouncing-balls

    效果如下: 代码目录如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charse ...

  9. python之设计模式

    一.简介 设计模式的定义:为了解决面向对象系统中重要和重复的设计封装在一起的一种代码实现框架,可以使得代码更加易于扩展和调用 四个基本要素:模式名称,问题,解决方案,效果 六大原则: 1.开闭原则:一 ...

  10. springboot 新模板 呵呵了

    <html> <head> <title>批处理任务管理</title> <meta name="decorator" con ...