LightOJ - 1282先頭と末尾の题解
効果の対象に
質問の意味:あなたが最初の3のパワーと番号の最後の3桁を求めるように、nはあなたにkは数を与えます。
\(2 <= N <2 ^ {31} \)、 \(1 <= K <10 ^ {7} \)
そして\(N ^ {kは} \ ) 少なくとも6桁を有します
問題解決のためのアイデア
このトピックでは、二つの問題を解決する必要があります
- 出力\(N ^ {K} \ ) トップ3の
- 出力\(N ^ {K} \ ) 3後
3つの出力した後、
これは、より良い迅速な電源を使用して解決され、剰余演算を行のコードを見て、ここでは詳細に説明されていない、解決することができます。
出力トップ3
これは、あまりにも面倒です\(^ nは{kが} \ ) 私たちは、この結果のビット数を削減する方法を見つけていること、でもlong long型は生き残ることができない、非常に大きくなることがあります。
どのようにそれを行うには?使用されるビットの数を軽減するために
\を[LG {N ^ {K }} = K * LG {N} \]
\ [N ^ {kは} = 10 ^ {LG {N ^ {K}}} = 10 ^ {k個*のLGN} \]
そのような\(k個*のLGNの\)整数部分は桁、小数部は精度を提供するために提供され、我々は、小数部を保持する整数を除去する必要があります。
なお、たとえ\(^ {10} 0.0001> 1 \) (指数関数に従って)、即ち、小数部電源10がゼロより大きい場合、我々は、この結果を100で乗算されますが、トップ3のキャリアである(AS 1)前に小数点を有しています。
コードの実装
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,k;
int qpow(int n,int k) //快速幂模板
{
int ans=1,base=n%1000;
while(k)
{
if(k%2==1)
{
ans=(ans*base)%1000;
}
base=(base*base)%1000;
k/=2;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1; i<=t; i++)
{
scanf("%d%d",&n,&k);
double a=(double)k*log10(n*1.0); //注意这个log函数的参数需要是浮点数,double类型
a-=(int)a; //去掉整数部分
double pre=pow(10.0,a); //求10的小数部分次幂
printf("Case %d: %d %03d\n",i ,(int)(pre*100),qpow(n, k)); //处理输出即可
}
}