SGU112 a^b-b^a
题目大意:
给你两个自然数a和b.求a^b-b^a.
输入
输入两个数 a 和 b (1≤a,b≤100).
输出
输出所求的答案.
样例输入
2 3
样例输出
-1
题目意思很好理解。
方法也很简单。
1.高精度乘法计算(大整数*大整数)。
2.套用快速幂(原理一样,即a^b=(a^(b/2))^2;(b为偶数)
a^b=(a^(b div 2))^2*a;(b为奇数)
注意事项:
1.高精度算法的正确性。
2.减法之前对符号的判断。
下面附上我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
struct big
{
int a[501];
}num1,num2,ans,zero,one;
int a,b;
struct big count1(struct big a,struct big b) //大整数a*大整数b
{
struct big re=zero;
int i,j,l;
for (i=1;i<=a.a[0];i++)
for (j=1;j<=b.a[0];j++)
{
re.a[i+j-1]+=a.a[i]*b.a[j];
re.a[i+j]+=re.a[i+j-1]/10;
re.a[i+j-1]%=10;
}
l=a.a[0]+b.a[0];
while (re.a[l]>=10)
{
re.a[l+1]+=re.a[l]/10;
re.a[l]%=10;
}
if (re.a[l]==0)
l--;
re.a[0]=l;
return re;
}
struct big count2(struct big a,int b) //大整数a*小整数b
{
struct big re=zero;
int i,j,l=a.a[0];
for (i=1;i<=l;i++)
{
re.a[i]+=a.a[i]*b;
re.a[i+1]+=re.a[i]/10;
re.a[i]%=10;
}
l++;
while (re.a[l]>=10)
{
re.a[l+1]+=re.a[l]/10;
re.a[l]%=10;
l++;
}
while (re.a[l]==0)
l--;
re.a[0]=l;
return re;
}
struct big dec(struct big a,struct big b) //计算大整数a-b
{
struct big re=zero;
int i,j,l=MAX(a.a[0],b.a[0]);
for (i=1;i<=l;i++)
{
re.a[i]+=a.a[i]-b.a[i];
if (re.a[i]<0 && i!=l)
{
re.a[i]+=10;
re.a[i+1]--;
}
}
while (re.a[l]==0)
l--;
re.a[0]=l;
return re;
}
struct big power(int a,int b) //快速幂a^b
{
struct big re=one;
if (b==0)
return re;
re=power(a,b/2);
re=count1(re,re);
if (b%2==0)
return re;
else
return count2(re,a);
}
int compare(struct big a,struct big b) //比较大整数a、b
{
int i;
if (a.a[0]>b.a[0])
return 1;
if (a.a[0]<b.a[0])
return 0;
for (i=a.a[0];i>=1;i--)
if (a.a[i]>b.a[i])
return 1;
else if (a.a[i]<b.a[i])
return 0;
return 1;
}
void init()
{
int i;
one.a[0]=one.a[1]=1;
scanf("%d%d",&a,&b);
num1=power(a,b);
num2=power(b,a);
if (compare(num1,num2)) //判断符号的输出
ans=dec(num1,num2);
else
{
printf("-");
ans=dec(num2,num1);
}
for (i=ans.a[0];i>=1;i--)
printf("%d",ans.a[i]);
printf("\n");
return ;
}
int main()
{
init();
return 0;
}