杭电网址:http://acm.hdu.edu.cn/showproblem.php?pid=1061
λ 题目描述:
Given a positive integer N, you shouldoutput the most right digit of N^N (1<=N<=1,000,000,000).
λ 输入样例:
3
4
λ 输出样例
7
6
解题思路:
- 先考虑基本的实现算法,sum=N^N,简单粗暴,但是数值太大会报错,时间复杂度也太高;
- 重新省视题目,要求输出最终个位上的值,那么考虑个位上数字(N%10)^N,减少了数值大小;
int sum = N%10;
n = N%10;
for (int i=1;i<N ; i++)
{
sum = sum*n;
sum = sum%10;
}
3.明显上面的虽然解决了数值问题,但是时间复杂度依旧没有改进,那么我们找一下循环是否存在规律,我们发现0-9确实存在规律
N N^1 N^2 N^3 N^4 N^5
0 0 0 0 0 0
1 1 1 1 1 1
2 2 4 8 6 2
3 3 9 7 1 3
4 4 6 4 6 4
5 5 5 5 5 5
6 6 6 6 6 6
7 7 9 3 1 7
8 8 4 2 6 8
9 9 1 9 1 9
那么我们发现它存在一个共有规律,每四次循环一次,那么我们的算法可以优化为:
while (scanf("%ld",&N) !=EOF)
{
int sum = N%10;
n = N%10;
int m = (N%4)+4;
for (int i =1; i < m; i++)
{
sum = sum * n;
sum = sum%10;
}
printf("%d\n",sum);
}
4.明显的现在完成了,但是它依旧不是最为简洁的,我们继续思考,通过0-9的表我们会发现具体数值存在的规律,特殊对待会使程序存在最优情况,还有特殊值、边值问题都可以进行 直接判断解决,增加效率:
long int N=0;
int n=0;
while (scanf("%ld",&N) !=EOF)
{
int sum = N%10;
n = N%10;
if (n ==0 || n ==1 || n ==5 || n ==6)
{
sum= n;
}
elseif (n ==2 || n ==3 || n ==4 || n ==7 || n ==8)
{
int m = (N%4)+4;
for (int i =1; i < m; i++)
{
sum = sum * n;
sum = sum%10;
}
}
else
{
int m = (N%2)+2;
for (int i =1; i < m; i++)
{
sum = sum * n;
sum = sum%10;
}
}
printf("%d\n",sum);
}
这是最后的优化代码了,本博客是自己学习总结所用,题目和杭电上有所不同,若有错误或者更好的办法望交流指出。谢谢。