当前位置: 代码迷 >> 综合 >> (快速幂模板)Rightmost Digit
  详细解决方案

(快速幂模板)Rightmost Digit

热度:49   发布时间:2023-11-03 01:06:58.0

快速幂模板:

long long PowerMod(long long a,long long b,long long c)  
{  long long ans = 1;  a=a%c;while(b>0)  {if(b%2==1) ans=(ans*a)%c;b=b/2;a=(a*a)%c;  }return ans;  
}  

Given a positive integer N, you should output the most right digit of
N^N.

Input

The input contains several test cases. The first line of the input is
a single integer T which is the number of test cases. T test cases
follow. Each test case contains a single positive integer
N(1<=N<=1,000,000,000).

Output

For each test case, you should output the rightmost digit of N^N.

Sample Input

2
3
4

Sample Output

7
6

Hint

In the first case, 3 * 3 * 3 = 27, so the rightmost digit is 7. In the
second case, 4 * 4 * 4 * 4 = 256, so the rightmost digit is 6.


题目意思就是求一个数n的n次方结果对10取模。首先我们来分析一下,整数n的最大取值是10的9次方,显然直接求解肯定会超时。这事我们可以通过快速幂算法来实现.
快速幂详解

#include <iostream>using namespace std;int pow1(int a,int b,int c)
{int ans=1;a=a%c;while(b>0){if(b&1)     /* 二进制这一位不为0 由于是二进制,很自然地想到用位运算这个强大的工具: & 和 >>.&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。>>运算比较单纯,二进制去掉最后一位*/ans=(ans*a)%c;a=(a*a)%c; //求二进制数每一位的权b>>=1;    //将b转化成二进制数按位右移,相当于b/=2;例如6>>1,即二进制数110,右移1位,变为011(2)=3(10)}return ans;
}int main()
{int t;cin>>t;while(t--){int n,n1,ans;cin>>n;n1=n%10;ans=pow1(n1,n,10);cout<<ans<<endl;}return 0;
}

当然对于这样的大型运算也有一定的规律可循,

#include <iostream>using namespace std;
int main()
{int t;cin>>t;while(t--){int n,n1,ans=1;cin>>n;n1=n%10;for(int i=1;i<=n%4+4;i++)//for(int i=0;i<=(n-1)%4;i++)//此处可换为 i < n%4 + 4;可解决n%4 ==0的情况    ans*=n1;cout<<ans%10<<endl;}return 0;
}
末位数      相乘后的末位数 
1           1 
2           4   8   6   2 
3           9   7   1   3 
4           6   4 
5           5 
6           6 
7           9   3   1   7 
8           4   2   6   8 
9           1   9(由于x9是奇数,所以1不会出现) 
0           0 由上面的分析可见,每个数相乘后最多有四个结果 
所以对一个数n,只需做其对4取余后余数次相乘即可 
但是会出现 n%4 == 0 的情况 
由于x5^x5的末位数是5,x9^x9的末位数是9 
所以将n%4转换为(n-1)%4