问题:找出N^N的最左边的一位数和最右边的一个数,N(1<=N<=1,000,000,000).
找最右边一位:
分析:其实找左右边的一位数还挺简单的,快速幂每次都只取结果的最后一位参加下一次运算,取最终结果的最后一位
找最左边一位:
可以用科学记数法表示N^N的计算结果,科学计数法表示的有效数的整数部分就是答案
输入一个N,
用科学计数法表示N^N = a * 10^n,其中a的整数部分只有一位
两边同时取对数,得到N*lg(N) = lg(a) + n
因为 1 < a < 10,所以0 < lg(a) < 1, 且n是整数,也就是说lg(a)是N*lg(N)的小数部分,n是N*lg(N)的整数部分,
那么10^(N*lg(N) - (int)N*lg(N))就是结果了
注意:结果比较大的时候可以用__int64或者long long(一样)
找最右边数题目:http://acm.hdu.edu.cn/showproblem.php?pid=1061
找最左边数题目:http://acm.hdu.edu.cn/showproblem.php?pid=1060
我的代码:
最右:
#include <stdio.h>
#include <math.h>
#define LL __int64
LL Qfact(LL n)
{
LL res = , pow = n;
while(n)
{
if(n & )
{
res *= pow;
res %= ;
}
pow *= pow;
pow %= ;
n /= ;
}
return res;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
LL n, ans;
scanf("%I64d", &n);
ans = Qfact(n);
printf("%I64d\n", ans%);
}
return ;
}
最左:(科学计数法)
#include <stdio.h>
#include <math.h>
#define LL __int64
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
LL n;
scanf("%I64d", &n);
double ans = n*log10(n*1.0);
ans = ans-(LL)ans;
ans = pow(10.0, ans);
printf("%I64d\n", (LL )ans);
}
return ;
}