首页 > 代码库 > <hdu - 1600 - 1601> Leftmost Digit && Rightmost Digit 数学方法求取大位数单位数字

<hdu - 1600 - 1601> Leftmost Digit && Rightmost Digit 数学方法求取大位数单位数字

1060 - Leftmost Digit

1601 - Rightmost Digit

 

  1060题意很简单,求n的n次方的值的最高位数,我们首先设一个数为a,则可以建立一个等式为n^n = a * 10^x;其中x也是未知的;

两边取log10有:lg(n^n) = lg(a * 10^x);

即:n * lg(n)  - x = lg(a);

现在就剩x一个变量了,我们知道x是值n^n的位数-1,a向下取整就是我们要求的数;

所以 按着上面的推导式翻译成代码就可以了(注意:数值的范围和之间的强制转换):

技术分享
 1 /*
 2  *   > File Name: 1060.cpp
 3  *   > Author: Ddlm2wxm
 4  *   > Mail: Ddlm2wxm@163.com 
 5  *   > Created Time: Wed 23 Nov 2016 09:36:14 PM CST
 6   ***************************************************************/
 7 
 8 #include<iostream>
 9 #include<cmath>
10 #include <cstdio>
11 using namespace std;
12 
13 typedef long long ll;
14 typedef long double ld;
15 
16 int main() {
17     int n;
18     ll num, ans;
19     ld t;
20     scanf("%d", &n);
21     while (n--) {
22         scanf("%lld", &num);
23         t = num * log10(num);
24         ans = pow (10,  (t - (ll)t));
25         printf("%lld\n", ans);
26     }
27     return 0;
28 }
1060

 

  1061和1060题意一样,只不过这道题是要求最低位上即个位上的数.在之间循环的时候有一些技巧:

①如果是偶数的话,直接第一次循环n * n % 10,然后更换n的值为n * n % 10;这样下一次乘的时候就是两个n和两个n来相乘了,所以我们需要另外找一个变量来进行n的减半操作;循环到底即可。

②如果是奇数的话,在进行减半操作之后,就会变成(n - 1) / 2的数,自然就会少一次n,所以我们需要当n为奇数时候使用res记录一下n的值。循环到底即可。

闲话不多话,上代码:

技术分享
 1 /*
 2  *   > File Name: 1061.cpp
 3  *   > Author: Ddlm2wxm
 4  *   > Mail: Ddlm2wxm@163.com 
 5  *   > Created Time: Wed 23 Nov 2016 09:40:03 PM CST
 6   *****************************************************************/
 7 
 8 #include <iostream>
 9 #include <algorithm>
10 #include <string>
11 #include <cstring>
12 #include <cstdio>
13 using namespace std;
14 
15 int mod_exp (int n) {
16     int res = 1, t = n % 10, b = n;
17     while (b) {
18         if (b & 1) {
19             res *= t;
20             res %= 10;
21         }
22         t *= t;
23         t %= 10;
24         b >>= 1;
25     }
26     return res;
27 }
28 
29 int main() {
30     int T, n;
31     scanf ("%d", &T);
32     while (T--) {
33         scanf ("%d", &n);
34         cout << mod_exp (n) << endl;
35     }
36     return 0;
37 }
1061

 

 欢迎码友一起评论更简单的方法,一起成长。

<hdu - 1600 - 1601> Leftmost Digit && Rightmost Digit 数学方法求取大位数单位数字