俱乐部每日一练 T^T(1)(快速幂)
Description
T ^ T这个很像一个流泪的表情是不是!其实,它是T的T次方啦~。当T比较大的时候T^T会非常大,现在只要你求这个数的个位就可以啦!
Input
输入包括多组测试数据,每个测试数据只有一个数字T(0<T<2^{31})T(0<T<2
31
)。
Output
请输出T^T的个位数。
Sample Input 1
1
2
3
105
Sample Output 1
1
4
7
5
- T^T的个位数即是T的个位数的T次方。将每个T的个位数的T次方的个位数列出来,观察可知个位数的变换是有规律的。
0 : 0
1 : 1
2 : 2 4 8 6
3 : 3 9 7 1
4 : 4 6
5 : 5
6 : 6
7 : 7 9 3 1
8 : 8 4 2 6
9 : 9 1
不同数的个位是在这几个数之间不断循环的,代码:
l=[[0],[1],[2,4,8,6],[3,9,7,1],[4,6],[5],[6],[7,9,3,1],[8,4,2,6],[9,1]]
while 1:
T=int(input())
a=T%10
if a==0:
print(0)
else:
b=T%len(l[a])
print(l[a][b-1])
- 用快速幂进行简化运算
快速幂的目的是进行快速求幂,假设求2^ 11 (a^b),将11拆为二进制为1101,原式变为2 ^(2 ^0+2 ^2+2 ^3)
再通过&位与运算(与一个数的二进制进行对位与运算)和>>(二进制去掉最后一位)进行运算,代码:
int poww(int a,int b){
int ans=1,base=a;
while(b!=0){
if(b&1!=0)
ans*=base;
base*=base;
b>>=1;
}
return ans;
}
如果b的二进制末尾为1,结果ans乘以这个位的底数值,一定要将底数值进行进位并去掉b二进制的最后一位,之后进入下一位的判断。
附上大佬对快速幂解释的网址:快速幂
对于这道题,因为输入的T可能原本就很大,所以对T及之后所得数对10进行取余。
代码:
#include <stdio.h>
int main()
{
int res,base1,base2;
while(scanf("%d",&base1)!=EOF){
res=1;
base2=base1%10;
while(base1>0){
if (base1&1!=0)
res=(res*base2)%10;
base2=(base2*base2)%10;
base1>>=1;
}
printf("%d\n",res);
}
return 0;
}