一种常见解法见链接:https://blog.csdn.net/gscsdlz/article/details/51886094
我数学不好想到了一个与众不同的解法。
求结果的前三位时,由于后面的数位对前三位的影响很小,所以不太重要,所以我们只要保证前若干位是精确的即可。这让我们想到可以用浮点数代替整数进行运算,后面不重要的数位会被自然舍弃,只保留前面的数位。
但是有一个问题,那就是浮点数能表示的数是有上限的,如果连续乘太多次会上溢。因此我们可以定义一个函数To1,将输入的double类型的x变成[1,10)上的数。
template<typename T>
void To1(T& x){
while(x >= 1){
10;
x /=
}10;
x *= }
每次运算完之后都把它重新放缩到[1,10),就可以防止上溢啦。最后结果的前三个十进制数字即为所求。
int solve3(int x, int ex){
double base = x;
To1(base);double ans = 1;
while(ex){
if(ex & 1){
To1(ans *= base);
}if(ex >>= 1){
To1(base *= base);
}
}while(ans < 1000)ans *= 10;
return (int)(ans / 10);
但是,放缩会丢失大小信息,如果结果本身没有达到1000,那最后结果就会被过度放大,比如n = 2, k = 8时,结果是64,但是该函数会返回640。所以一开始先检查一下结果是否大于1000,如果不是则直接返回该结果。完整的函数如下:
int solve3(int x, int ex){
1;
LL tmp = for(int i = 1; i <= ex; ++i){
tmp *= x;if(tmp >= INT_MAX)break;
}if(tmp < INT_MAX){
Remain3(tmp);return (int)tmp;
}
double base = x;
To1(base);double ans = 1;
while(ex){
if(ex & 1){
To1(ans *= base);
}if(ex >>= 1){
To1(base *= base);
}
}while(ans < 1000)ans *= 10;
return (int)(ans / 10);
}
其中的Remain3函数提取出输入参数的前三个有效数字:
template<typename T>
void Remain3(T& x){
while(x >= 1000){
10;
x /=
} }
求出结果的后三位有效数字用普通的快速幂对1000取模即可。完整AC代码如下:
#include <stdio.h>
#include <limits.h>
using namespace std;
typedef long long LL;
template<typename T>
int ex, T p)
T mpow(T base,
{
base %= p;1;
T ans = while(ex)
{if(ex & 1)
(ans *= base) %= p;if(ex >>= 1)
(base *= base) %= p;
}return ans;
}
template<typename T>
void To1(T& x){
while(x >= 1){
10;
x /=
}10;
x *=
}
template<typename T>
void Remain3(T& x){
while(x >= 1000){
10;
x /=
}
}
int solve3(int x, int ex){
1;
LL tmp = for(int i = 1; i <= ex; ++i){
tmp *= x;if(tmp >= INT_MAX)break;
}if(tmp < INT_MAX){
Remain3(tmp);return (int)tmp;
}
double base = x;
To1(base);double ans = 1;
while(ex){
if(ex & 1){
To1(ans *= base);
}if(ex >>= 1){
To1(base *= base);
}
}while(ans < 1000)ans *= 10;
return (int)(ans / 10);
}
int main() {
int n, k;
int T;
int ans_trailing;
"%d", &T);
scanf(for(int Ti = 1; Ti <= T; ++Ti){
"%d%d", &n, &k);
scanf(1;
ans_trailing = for(int i = 1; i <= k; ++i){
ans_trailing *= n;if(ans_trailing >= 1000)break;
}
"Case %d: %d ", Ti, solve3(n, k));
printf(if(ans_trailing >= 1000){
"%03d\n", mpow(n, k, 1000));
printf(else{
}"%d\n", ans_trailing);
printf(
}
}return 0;
}
第一次写题解,如有不妥欢迎指出~