问题链接:HDU1013 Digital Roots。
问题分析:
这个问题是对于输入的n,计算n^n的数根。给出两种解题思路如下:
解法一:
先看一下以下式子:
因为:(10*a+b)*(10*a+b)=100*a*a+10*2*a*b+b*b
所以右边式子的数根(中间结果,也是左边式子的数根)为:a*a+2*a*b+b*b=(a+b)*(a+b)
故:对于两位数n,n*n的数根=n的树根×n的树根。
同理可以推出,对于任意位数的n,也满足:n*n的数根=n的树根×n的树根。
程序中,实现一个计算整数数根的函数,利用这个函数来计算n^n的数根。
解法二:
计算n^n的数根,一要快,二要简单。使用快速模幂计算,加上数论中的九余数定理就完美了。
AC的C++语言程序如下(解法二):
/* HDU1163 Eddy's digital Roots */
#include
using namespace std;
const int NICE = 9;
// 快速模幂计算函数
int powermod(int a, int n, int m)
{
int res = 1;
while(n) {
if(n & 1) { // n % 2 == 1
res *= a;
res %= m;
}
a *= a;
a %= m;
n >>= 1;
}
return res;
}
int main()
{
int n, ans;
while(cin >> n && n) {
ans = powermod(n, n, NICE);
cout << (ans ? ans : 9) << endl;
}
return 0;
}
AC的C语言程序如下(解法一):
/* HDU1163 Eddy's digital Roots */
#include
// 计算数根函数
int digitalroots(int val)
{
int result, temp;
while(val) {
result = 0;
temp = val;
while(temp) {
result += temp % 10;
temp /= 10;
}
if(result < 10)
break;
val = result;
}
return result;
}
int main(void)
{
int n, ans, nr, i;
while(scanf("%d", &n) != EOF) {
if(n == 0)
break;
// 计算n的数根
ans = nr = digitalroots(n);
// 计算n^n的数根
for(i=2; i<=n; i++) {
ans = digitalroots(ans * nr);
}
// 输出结果
printf("%d\n", ans);
}
return 0;
}