题意:
给出两个整数n和k,计算n^k的结果的前三个数字和最后三个数字,数据范围比较大
题解:
对于后面的三位数使用快速幂取模运算即可计算出来。前面三位数字则需要一些数学转换,
, 我们把
的结果拆分成整数部分z和小数部分p可得
,显然
得到的结果为100000…….(一个1后缀为k个0)的数字,而前面的三位数则由后面的
决定,计算出
结果后乘上100即为前三位(题目中数据保证了一定存在,所以可以直接乘100)
坑点:
- 暴力会virtify为TLE
- 后三位需要考虑前导0,输出使用%03lld或%03d
AC代码:
#include <iostream>
#include <stdio.h>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const ll inf = 0x3f3f3f3f;
typedef long double ld;
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
inline ll mul(ll x, ll y, ll mod) {ll res = (x * y - (ll)(ld)(x / mod * y + 1e-8) * mod); return res < 0 ? res + mod : res;}
const double PI = acos(-1.0);
const int mod = 1000;
ll qPow(ll base, ll n) {ll res = 1; while(n) {if(n & 1) res = (res * base) % mod; base = (base * base) % mod; n >>= 1;} return res % mod;}
int main() {
int T, cas = 1;
ll n, k;
scanf("%d", &T);
while(T--) {
scanf("%lld%lld", &n, &k);
double t = (double)k * log10((double)n);
ll res1 = (ll)(pow(10.0, (double)(fmod(t, 1.0))) * 100.0);
ll res2 = qPow(n, k);
printf("Case %d: %lld %03lld\n",cas++, res1, res2);
}
return 0;
}