题目来源,多校联合赛: http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=16820&pid=1002(重开,密码:52acm8)
注意:貌似过了这段时间不能提交了的说。。。。。。
3 123456 1 123456 2 2100000056 67333
123...456 152...936 982...016
//巧妙的思想,后三位用幂取模可以求出注意补0,
//总位数可利用t=k*log10((double)n)+1 向上取整求出,
//前三位根据方程head=n^k/(10^(t-3))求出
//注意:1求一个数的位数就是把它对10取对数,然后加1即可(科学计数法)
// 2求lnx为log(x);求lgx为log10(x);求以n为底的就是logn();(还好kb神提醒了这一点。。。)
// 3注意重载函数log的调用(强制类型转换,并且加上头文件#include):
// “long double log(long double)”
// “float log(float)”
// “double log(double)”
//推荐一道求n的阶乘的位数的题目hdu 1018 (斯特林公式)
//31 MS 276 KB Visual C++
#include
#include
#include
using namespace std;
int pow_mod(int a,int n,int m)//就是那个很快的求a^n%m的快速幂的函数,可以去看下我的那个快速幂模板的博客
{
if(n==0)
return 1%m;
int ret=1;
while(n>0)
{
if(n&1)
{
ret=(ret*a)%m;
}
n>>=1;
a=(a*a)%m;
}
return ret;
}
int main()
{
int T,n,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
int t=k*log10((double)n)+1;//求n^k的位数,科学计数法思想。。。
int head,tail;
tail=pow_mod(n%1000,k,1000);
for(head=100;log((double)head)<=k*log((double)n)-(t-3)*log((double)10);head++);//注意这里的分号';',区别于我们平时的for()循环,中间的表示head<=n^k/10^(t-3);数学问题毕竟是要写在纸上才看的懂的
head--;//因为前面的for()中多加了一位,所以这里head减去一位
printf("%3d...%03d\n",head,tail);
}
return 0;
}
代码二:看了kb神的代码后,改的我比赛时错的代码
/*
float的范围为-2^128~+2^128,也即-3.40E+28~+3.40E+38;
double的范围为-2^1024~+2^1024,也即-1.79E+308~+1.79E+308.
*/
//更正的代码(改成double就对了。。。long long桑不起啊):0 MS 260 KB Visual C++
#include
const double mod=1e20;//精度问题桑不起啊!!!
const int m1=1000;
int pow1_mod(__int64 m,int n)//求m^n%1000的快速幂函数,不解释。。。(求后三位)
{
int b=1;
m%=m1;
if(n==1)
return m;
while(n>0)
{
if(n&1)
{
b=(b*m)%m1;
}
n=n>>1;
m=(m*m)%m1;
}
return b;
}
int pow2_mod(__int64 m,int n)//截取前面很长的一段(那么后面的数对于前三位的影响就很小了,精度问题永远都是硬伤啊),然后不停的相乘,不停的取模(求前三位)
{
double b=1;
double temp=(double)m;
while(temp>mod)
temp/=10;
while(n>0)
{
if(n&1)
{
b=(b*temp);
while(b>mod)
b/=10;
}
n=n>>1;
temp=temp*temp;
while(temp>mod)
m=temp/=10;
}
while(b>=m1)
b/=10;
return (int)b;
}
int main()
{
int test;
__int64 n;
int k;
int ans1,ans2;
while(scanf("%d",&test)!=EOF)
{
while(test--)
{
scanf("%I64d%d",&n,&k);
ans1=pow2_mod(n,k);
ans2=pow1_mod(n,k);
printf("%d...%03d\n",ans1,ans2);
}
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
const double qq=1e20;
int solve1(long long a,int n)
{
a%=1000;
int temp=a;
int ret=1;
while(n)
{
if(n&1)
{
ret*=temp;
ret%=1000;
}
temp*=temp;
temp%=1000;
n>>=1;
}
return ret%1000;
}
int cal2(long long a,int n)
{
double ret=1;
double temp=(double)a;
while(n)
{
if(n&1)
{
ret*=temp;
while(ret>=qq)ret/=10;
}
temp*=temp;
while(temp>=qq)temp/=10;
n>>=1;
}
while(ret>=1000)ret/=10;
return (int)ret;
}
int main()
{
// freopen("A.in","r",stdin);
// freopen("A.out","w",stdout);
// printf("%lf\n",qq);//高精度,桑不起啊
long long a;
int n;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%I64d%d",&a,&n);
// printf("%d\n",cal2(a,n));
printf("%d...%03d\n",cal2(a,n),solve1(a,n));
}
return 0;
}
//更正后的标程46 MS 276 KB Visual C++
#include
#include
#include
using namespace std;
int pow_mod(int a,int n,int m)
{
if(n==0)
return 1%m;
long long x=pow_mod(a,n/2,m);
x=(x*x)%m;
if(n%2)
x=(x*a)%m;
return (int)x;
}
int main()
{
int T,n,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
int t=k*log10((double)n)+1,head,tail;
tail=pow_mod(n%1000,k,1000);
for(head=100;log((double)head)<=k*log((double)n)-(t-3)*log((double)10);head++);
head--;
printf("%3d...%03d\n",head,tail);
}
return 0;
}