题目链接:http://poj.org/problem?id=1423
题目大意:给定一个数,求阶乘的位数
思路:给一个数n,求n的阶乘的位数;直接高精度计算显然很复杂,换个思路,对于一个数m,m的位数就是(int)log10(m)+1。如果m=n*(n-1)*(n-2)*......*1,那么log10(m)=log10(n)+log10(n-1)+.....+log10(2)+log10(1)。即m的位数是( int )( log10(n)+log10(n-1)+.....+log10(2)+log10(1) )+1。由于题目要求的m很大,独立计算会造成重复计算某些值,所以采用预处理。
代码:
//做过的第一道题目是把所有用例输入联系起来的,因为大数的用例要用到小数的用例
//先将所以要求的数都存起来,由于最后要按输入顺序输出结果,所以还要存入id
//按值从小到大顺序排列,先计算最小值的对数,后面的数都建立在他的基础上,
//和上述代码思路相同。最后按id从小到大排列输出结果即可,这样可以避免对内存的溢出
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
struct node{
int id, num;
double result; //对数的和 所以用double
}a[1010];
int flag;
int cmp(node c, node d)
{
if(flag)
return c.num<d.num; //从小到大排序
return c.id<d.id;
}
int main()
{
int n;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>a[i].num;
a[i].id = i;
a[i].result = 0;
}
flag = 1;
sort(a,a+n,cmp);
for(int i=1;i<=a[0].num;i++)
a[0].result+=log10(i);
for(int i=1;i<=n;i++)
{
a[i].result+=a[i-1].result;
for(int j=a[i-1].num+1;j<=a[i].num;j++)
a[i].result+=log10(j);
}
flag = 0;
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
cout<<(int)a[i].result + 1<<endl; //因为是double 最后转为int
}
return 0;
}