今天第二天,觉得自己从题目中获取的东西不少,所以对编程题目也比较越来越有兴趣--这是个不错的开端,所以希望自己能继续玩下去。
接下来看一道又是用到“记忆搜索”思想的题目吧----继续吐槽一遍,这”记忆搜索“真是高大上~希望能加深领悟这种思想。
=======================================================================================================
题目描述:
从键盘输入一个自然数K(99999999>K>1),若存在自然数M和N(M>N),使得K的M次方和K的N次方均大于或等于1000,
且它们的未尾三位数相等,则称M和N是一对“K尾相等数”。请编程序,输出K尾相等数中M+N最小值。
输入样例
2
输出样例
120
=======================================================================================================
思考过程:
首先,观察易知用直接k的m次方和k的n次方进行判断是不科学的,题目要求判断的只是”末尾三位数“,所以我们只要取k的m次方和k的n次方
的末尾三位数即可--取余1000即可。
”记忆搜索“思想的体现:
每次我们判断的时候都会用到之前用过的末尾三位数--重复使用之前的结果。
所以这里我们用一个数组来保存”x次幂的值“的末尾三位数,之后判断的时候直接拿来用就好了
=========================================================================================================
源代码:
#include <stdio.h>
#include <math.h>
int tail[1000];//用来记录k的x次幂的末尾三位数
int findMin(int k)
{
for (int i = 1;; ++i)
if (pow((double)k, i) > 1000)
return i;
}
int main()
{
int k;
scanf("%d", &k);
int min = findMin(k);//findMin函数用来找出最小的i幂,使得k的i次幂大于等于1000,因为再小的幂我们用不到
tail[min] = (int)pow((double)k, min) % 1000;
for (int i = 2 * min + 1;; ++i) {
int m = i - min, n = min;
tail[i - min] = tail[i - min - 1] * k % 1000;//记忆搜索的体现
for (; m > n; m--, n++) {
if (tail[m] == tail[n]) {//记忆搜索的体现
printf("%d\n", m + n);
return 0;
}
}
}
}
=========================================================================================================