本文主要讲述快速幂的得到:计算(a^b)%c :
代码一
#include<stdio.h>
int main(void)
{
int ans=1;
int a;
int i;
int b;
int c;
scanf("%d%d%d",&a,&b,&c);
for (i = 1; i <= b; i++)
{
ans = ans*a;
}
printf("%d",ans%c);
getchar();
getchar();
return 0;
}
这种方法是直接按照公式展开的,效率低,
代码二:
//(a^b)%c=(a%c)^b%c
#include<stdio.h>
int main(void)
{
int ans = 1;
int a;
int i;
int b;
int c;
scanf("%d%d%d", &a, &b, &c);
a = a%c;//先对a进行取余运算
for (i = 1; i <= b; i++)
{
ans = ans*a;
}
printf("%d\n", ans%c);//最后再对乘方的结果进行取余运算
getchar();
getchar();
return 0;
}
代码三:
//(a^b)%c=(a%c)^b%c
#include<stdio.h>
int main(void)
{
int ans = 1;
int a;
int i;
int b;
int c;
scanf("%d%d%d", &a, &b, &c);
a = a%c;//先对a进行取余运算
for (i = 1; i <= b; i++)
{
ans = ( ans * a ) % c;//此处对乘积的因子取余,结果并不改变
}
printf("%d\n", ans%c);//最后再对乘方的结果进行取余运算
getchar();
getchar();
return 0;
}
代码四:
//快速幂
//a^b%c=((a^2)^(b/2))%c偶数
//a^b%c=((a^2)^(b/2)*a)%c奇数
#include<stdio.h>
int main(void)
{
int ans = 1;
int a;
int i;
int b;
int c;
int k;
scanf("%d%d%d", &a, &b, &c);
if (b % 2 == 1)//检验奇偶性
{
ans = (ans*a) % c;//奇数要多算一次
}
k = (a*a) % c;//算k
for (i = 1; i <= b/2; i++)
{
ans = (ans * k) % c;
}
printf("%d\n", ans%c);//最后还要取一次余
getchar();
getchar();
return 0;
}
代码五,便是我们常用的快速幂算法模板:
/*但我们可以看到,当我们令k = (a * a) mod c时,状态已经发生了变化,
我们所要求的最终结果即为(k)b/2 mod c而不是原来的ab mod c,所以我们发现这个过程是可以迭代下去的。
当然,对于奇数的情形会多出一项a mod c,所以为了完成迭代,当b是奇数时,我们通过
ans = (ans * a) % c;来弥补多出来的这一项,此时剩余的部分就可以进行迭代了。
形如上式的迭代下去后,当b=0时,所有的因子都已经相乘,算法结束。
于是便可以在O(log b)的时间内完成了。于是,有了最终的算法:快速幂算法。
*/
#include<stdio.h>
int main(void)
{
int ans = 1;
int a;
int i;
int b;
int c;
int k;
scanf("%d%d%d", &a, &b, &c);
a = a%c;//先进行一步取余操作
while (b > 0)
{
if (b % 2 == 1)//如果为奇数的话
{
ans = (ans*a) % c;//多一步
}
b = b / 2;//迭代b/2
a = (a*a) % c;//迭代
}
printf("%d\n", ans%c);//最后以后还要进行一次取余操作
getchar();
getchar();
return 0;
}