找出N^N的最左边的一位数和最后边的一位数
问题:找出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 = 1, pow = n; while(n) { if(n & 1) { res *= pow; res %= 10; } pow *= pow; pow %= 10; n /= 2; } return res; } int main() { int t; scanf("%d", &t); while(t--) { LL n, ans; scanf("%I64d", &n); ans = Qfact(n); printf("%I64d\n", ans%10); } return 0; }
最左:(科学计数法)
#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 0; }