Description
今天,小胖出门买切糕,大家都知道,切糕是密度是相当的大,所以切糕的质量要用指数来计算。买买提(切糕商)说:买多少,切多少。结果变成切多少,买多少。由于小胖的气场,买买提最终决定,把一块质量为a^b的切糕,分为c块,多余出来质量为d的卖给小胖,求小胖需要买多少切糕。
Input
输入数据有多组,每组占一行,由三个整数a,b,c,当a=0,b=0,c=0时,表示输入结束,该行不做处理。0<a,c<1000 0=<b<1000
Output
很简单,你只要求出d的值
Sample Input
3 2 3 4 3 3 0 0 0
Sample Output
0 1
首先要知道,a^b是a的b次方的意思。
然后重要的就是取模运算。
一开始我以为就是简单的取余,写出的代码就是wrong answer.(如下)
#include<stdio.h>
int main(void)
{
int a,b,c,d,i,t;
while (~scanf("%d %d %d",&a,&b,&c))
{
t=1;
if(a==0&&b==0&&c==0)break;
for(i=1;i<=b;i++)t=t*a;
d=t%c;
printf("%d\n",d);
}
return 0;
}
存在最主要的问题就是数据溢出(指数具有爆炸性增长)
所以改成以下这样就可以了:
#include<stdio.h>
int main(void)
{
int a,b,c,d,i;
while (~scanf("%d %d %d",&a,&b,&c))
{
if(a==0&&b==0&&c==0)break;
d=a%c;
for(i=1;i<b;i++)
d=(d*a)%c;
printf("%d\n",d);
}
return 0;
}
百度百科中对取模运算的定义是:取模运算(Modulo Operation)和取余运算(Remainder Operation)两个概念有重叠的部分但又不完全一致。主要的区别在于对负整数进行除法运算时操作不同。取模主要是用于计算机术语中。取余则更多是数学概念。
王法波编著的《从零开始学Java》中的定义如下
我们需要知道(以下内容摘自百度百科):
(感兴趣的同学可以自己再深入了解)
1. 各个环境下%运算符的含义不同,比如c/c++,java 为取余,而python则为取模。
2.同余式:正整数a,b对p取模,它们的余数相同,记做 或者a ≡ b (mod p)。
3.n % p 得到结果的正负由被除数n决定,与p无关。例如:7%4 = 3, -7%4 = -3, 7%-4 = 3, -7%-4 = -3。
4.运算规则:模运算与基本四则运算有些相似,但是除法例外。(除法例外!!)
(1)(a + b) % p = (a % p + b % p) % p
(2)(a - b) % p = (a % p - b % p ) % p
(3)(a * b) % p = (a % p * b % p) % p
(4)a ^ b % p = ((a % p)^b) % p
5.利用模运算的运算规则,我们可以使某些计算得到简化。(模幂运算)
例如,我们想知道3333^5555的末位是什么。很明显不可能直接把3333^5555的结果计算出来,那样太大了。但我们想要确定的是3333^5555(%10),所以问题就简化了。
根据运算规则(4)a^b % p = ((a % p)^b) % p ,我们知道3333^5555(%10)= 3^5555(%10)。
根据运算规则(3) (a * b) % p = (a % p * b % p) % p ,由于5555 = 4 * 1388 + 3,我们得到3^5555(%10)=(3^(4*1388) * 3^3)(%10)=((3^(4*1388)(%10)* 3^3(%10))(%10)=((3^(4*1388)(%10)* 7)(%10)。
根据欧拉定理可以得到 3 ^ (4 * k) % 10 = 1, 所以((3^(4*1388)(%10)* 7)(%10)= (1 * 7) (% 10) = 7,计算完毕。
利用这些规则我们可以有效地计算X^N(% P)。简单的算法是将result初始化为1,然后重复将result乘以X,每次乘法之后应用%运算符(这样使得result的值变小,以免溢出),执行N次相乘后,result就是我们要找的答案。
这样对于较小的N值来说,实现是合理的,但是当N的值很大时,需要计算很长时间,是不切实际的。下面的结论可以得到一种更好的算法。
如果N是偶数,那么X^N =(X*X)^[N/2];
如果N是奇数,那么X^N = X*X^(N-1) = X *(X*X)^[N/2];
其中[N]是指小于或等于N的最大整数。
(所以也有同学分奇偶来进行解决)
(代码如下,摘自文章http://t.csdnimg.cn/qAl4J)
/*快速幂模板*/
int quickPow(int a,int b,int n)
{
if(b==1)return a;
if(b%2==0) //偶数
{
int t=quickPow(a,b/2,n);
return t*t%n;
}
else{ //奇数
int t=quickPow(a,b/2,n);
t=t*t%n;
t=t*a%n;
return t;
}
}