AOJ 758.大数的位数

大数的位数

Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MB
Total Submission: 30   Submission Accepted: 9

Description

给出一个整数,确定这个数的阶乘的位数。

Input

多组数据,每行为一个大于等于1且小于等于107的整数n.

Output

对应每个输入数据输出一个结果。

Sample Input

Original Transformed
10
20

Sample Output

Original Transformed
7
19

两种方法可能可以实现:

  1. 抛去一定的精度来计算
  2. 采用数学公式计算

对于第一种方法,我们可以得知,对于两个大数相乘,其较低位对结果的影响较小,因此我们可以舍弃一些数据

采用类似于科学记数法的形式来计算(a*10^b)

这种做法,当n较大时,会由于误差的累积导致错误。

而第二种方法可以采用一些数学公式计算

log10n! = log10(1*2*3*......*n) = log101+log102+log103+...+log10n

显然,等式右侧我们可以轻易得出。

而等式左侧,log10n的意义是n对10的对数,即10log10n=n

对于一个整数k,若10k<n<10k+1,我们可以得出结论,n是k位数

所以,大数n!的位数就是log10n!,由于int的向下取整性质,我们还要将这个数再加上1

虽然题目上说的最大值是107,然而,最大值至少是197(方法1WA)

AC代码:GitHub

 1 /*
 2 By:OhYee
 3 Github:OhYee
 4 HomePage:http://www.oyohyee.com
 5 Email:[email protected]
 6 Blog:http://www.cnblogs.com/ohyee/
 7
 8 かしこいかわいい?
 9 エリーチカ!
10 要写出来Хорошо的代码哦~
11 */
12
13 #include <cstdio>
14 #include <algorithm>
15 #include <cstring>
16 #include <cmath>
17 #include <string>
18 #include <iostream>
19 #include <vector>
20 #include <list>
21 #include <queue>
22 #include <stack>
23 #include <map>
24 using namespace std;
25
26 //DEBUG MODE
27 #define debug 0
28
29 //循环
30 #define REP(n) for(int o=0;o<n;o++)
31
32 const int maxn = 10005;
33 bool tree[maxn];
34
35 int bit(int n) {
36     int a = 1;
37     int e = 0;
38
39     for(int i = 1;i <= n;i++) {
40         a *= i;
41         while(a / 100000) {//保证精度
42             a /= 10;
43             e++;
44         }
45     }
46
47     while(a) {//转化为位数
48         a /= 10;
49         e++;
50     }
51
52     return e;
53 }
54
55 //n! = 1*2*3*4*5*......*(n-1)*n
56 //ln n! = ln 1+len2+......ln(n-1)+ln n
57 int mathbit(int n) {
58     double ans = 0;
59     for(int i = 1;i <= n;i++)
60         ans += log10(i);
61     return (int)ans+1;
62 }
63
64
65 bool Do() {
66     int n;
67     if(scanf("%d",&n) == EOF)
68         return false;
69
70
71     printf("%d\n",mathbit(n));
72     return true;
73 }
74
75 int main() {
76     while(Do());
77     return 0;
78 }
时间: 2024-10-18 07:13:47

AOJ 758.大数的位数的相关文章

poj1423---求一个大数的位数方法,我猜网站上统计输入字符少于多少位的那个算法

法一:对一个数求它的对数,+1取整为其位数 问题转化为int (log10(N!)+1),对数性质log10(N!)=log10(N)+log10(N-1)+...+log10(1) /*用log10求位数*/ #include<stdio.h> #include<math.h> int main() { int tim,N; scanf("%d",&tim); while(tim--) { int i; double NumOfDigit=1; sca

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

http://acm.hdu.edu.cn/showproblem.php?pid=1018 Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 41932    Accepted Submission(s): 20544 Problem Description In many applications very lar

大数处理 详解 模版

1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<set> 9 #include<stack> 10 #include<string> 1

简单实现大数相加

思路: 使用字符串来表示大数,然后对两个数字字符串使用类似列竖式的方式进行逐位相加求和. 123 +   24 _____  147 具体实现: char* BigNumberAddition(const char* number1, const char* number2) { if (!number1 || !number2) { return NULL; } int len1 = strlen(number1); int len2 = strlen(number2); //两个数相加 结果

c++大数板子

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; /* * 完全大数模板 * 输出cin>>a * 输出a.print(); * 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数. * by kuangbin GG. */

大数模板 poj3982

1. 这个模板不是自己写的,转载的别人转载的,还没学完c++的我,想写也没有那能力. 这个模板我用在了POJ的一道题上,传送门--POJ3982 一般大数的题,都可用这个模板解决,仅仅须要改动主函数就好了,可是假设不能独立写出来的话,不相当于白搭吗.所以我学完c++后会手写出模板的!. 注意,这个大数模板仅仅适用于不太大的模拟,几万位,肯定会爆内存的,兴许会补上功能更强大的模板和JAVA大数模板. #include<iostream> #include<cstdio> #inclu

大数问题(高精度运算)

一.基本概念 在某些情况下,我们必须处理相当大的一个整数,运用类型int.long int.long long int 类型均无法对其进行存储.要解决这样的问题,我们就需要自己编写相应的处理程序.在处理大数的时候,可以将其作为字符串读入,然后一个数字一个数字的存储到数组中,然后编写相应运算操作的处理函数即可解决大数问题. 也就是说在对大数进行运算之前,要先解决对大数进行存储的问题.而这里一一般情况为例,对输入和输入函数进行定义. 输入处理: 输入字符串: c[0] c[1] c[2] c[3]

大数计算

#include<iostream> #include<stdint.h> #include<algorithm> #include<map> #include<set> #include<vector> #include<queue> #include<stack> #include<math.h> #include<iostream> #include<string> #

大数问题 加减乘除余 有参考部分网络代码如除法和减。其余原创。

大数问题集训会教案 大数问题,其实就是模拟运算,因为系统自带的int long bouble这些类型无法容纳百位千位的大数字,从而手动模拟运算过程,使用字符串来表示这样的超大数字,如果你会Java的话就简单多了,直接有一个大数类,可以像用函数一样直接调用,不过,那个是大三学滴. 大数问题适用的问题,一般是大数阶乘,大数加减乘除余方,这个嘛请参照南阳大数类型题,难度一般是省赛中最简单的3题之一. 废话不说,直接上思路先. 问题一:如何输入输出 问题二:小学生的个位与多位加法是怎么运算的?如何逆转字