HDOJ 1061 Rightmost Digit
http://acm.hdu.edu.cn/showproblem.php?pid=1061
这道题目的意思是,给你一个很大的整数N(1<=N<=1,000,000,000),要你求N的N次方的最后一位数字,
一开始想到用一个数字保留每次乘法的个位数,但是超时了,
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 long n,m,num,p; 5 cin>>num; 6 while(num--){ 7 cin>>n; 8 m = p = n % 10; 9 while(--n){ 10 p = (p * m) % 10; 11 } 12 cout<<p<<endl; 13 } 14 return 0; 15 }
然后,想不出就百度呗,发现这道题目是有规律可循的,它的所有解最后会掉入到一个循环中,这个循环的周期是4,
1(次方) | 2(次方) | 3(次方) | 4(次方) | 5(次方) | 6(次方) | 7(次方) | 8(次方) | 9(次方) | |
1(结尾) | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2(结尾) | 2 | 4 | 8 | 6 | 2 | 4 | 8 | 6 | 2 |
3(结尾) | 3 | 9 | 7 | 1 | 3 | 9 | 7 | 1 | 3 |
4(结尾) | 4 | 6 | 4 | 6 | 4 | 6 | 4 | 6 | 4 |
5(结尾) | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
6(结尾) | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
7(结尾) | 7 | 9 | 3 | 1 | 7 | 9 | 6 | 1 | 9 |
8(结尾) | 8 | 4 | 2 | 6 | 8 | 4 | 2 | 6 | 8 |
9(结尾) | 9 | 1 | 9 | 1 | 9 | 1 | 9 | 1 | 9 |
下面是copy别人的代码,
1 #include <stdio.h> 2 int n,tt,f,i,t; 3 int main() 4 { 5 //这道题目有规律,题目只要求输出最后一位,所以我们只关注最后一位 6 //阿拉伯数字的神奇之处就是可以只用十种数字就可以表示出无数的数字 7 //1.先来看1的情况,1的n次都为1,所以1的次幂的个位有最小周期1 8 //2.再来看2的情况,2的n次,个位依次位2,4,8,6,2……看到最小周期是4 9 //还要看吗? 10 //归纳以下可得任何数的n次幂的个位都有一个周期是4 11 scanf("%d",&t); 12 while(t--)//t存放的是执行次数, 13 { 14 scanf("%d",&n);//n存放着输入的数据, 15 f=n%10;//f存放着n的个位数, 16 if(n%4==0)//这里把n从一个很大的数变成一个很小的数,1,2,3,4 17 { 18 n=4; 19 }else 20 n%=4; 21 tt=1;//然后计算f的n次 22 for(i=0;i<n;i++) 23 { 24 tt=tt*f; 25 } 26 printf("%d\n",tt%10); 27 } 28 return 0; 29 }
之后,我把之前自己写的代码做了一些修改,也AC了,
#include<iostream> using namespace std; int main(){ long n,m,num,p; cin>>num; while(num--){ cin>>n; m = p = n % 10; if (n % 4 == 0)//这个判断,把n缩小到了,1,2,3,4, { n = 4; } else { n = n % 4; } while(--n){ p = (p * m) % 10; } cout<<p<<endl; } return 0; }