题目大意:给你两个数n,m,要你求出n^m结果的后三位是什么以及前三位是什么。
思路:
后三位的话容易,就是求快速幂mod1000即可。下面附带一下快速幂的写法,自己也复习一下。
int pow_mod(int n, int k)
{
if (k == 0)return 1;
long long x;
x = pow_mod(n, k >> 1);
x = x*x%mod;
if (k & 1)return (x*n%mod);
return x;
}
那对于前三位的求法,则是一种技巧。
首先n用科学计数法表示n=y*10^x;那么n^m=y^m*10^(x+m)其中,我们要求解前三位,而10^(x+m)显然可以不考虑,我们只需要考虑y^m即可。最终的答案是y^m*100
这边我们就对两边取10的对数,得到m*(log(y)+x)其中y<e,所以log(y)<1,x为整数,所以我们只需要分离出log(y),然后反向处理就可以了。说的不是很清楚,大家看代码就懂了
/*
求一个数m次方的前三位和后三位
后三位的方法自然是快速幂求模1000
前三位的方法比较巧妙。
一个数假设是x=123456,用科学计数法进行表示就是1.23456*10^5,
*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define mod 1000
int pow_mod(int n, int k)
{
if (k == 0)return 1;
long long x;
x = pow_mod(n, k >> 1);
x = x*x%mod;
if (k & 1)return (x*n%mod);
return x;
}
int main()
{
double intpart;
int n, k;
int t;
cin >> t;
int icase = 1;
while (t--)
{
scanf("%d%d", &n, &k);
//modf(double,double*)的作用就是将第一个数的整数部分和小数部分分开,小数部分返回,整数部分存入第二个变量。
//这边+2.0的作用就在于*100,因为得出来的数是log(y)所以我们要进行幂处理得到y然后再乘以100
printf("Case %d: %d %03d\n", icase++,(int)pow(10, 2.0 + modf((double)(k*log10(n)), &intpart)), pow_mod(n, k));
}
}