ZCMU 1104:小胖买切糕

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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值