描述
计算a的b次方对9907取模的值。
输入
第一行有一个正整数T,表示有T组测试数据。
接下来T行,每行是一组测试数据,包含两个整数a和b。
其中T<=10000, 0 <=a,b < 2^31。
输出
有T行,依次输出每组数据的结果。
样例输入
31 22 33 4
样例输出
1881
这个题网上好多牛人都发布了解法,但是大多数程序运行都超时。
基本思想是函数递归,这个在好多人的代码中都体现了。常规的递归在这里是不行的。
用到的思想是动态规划法和二分法。动态规划讲求的是只做有用的事,不做重复的事,以空间换取时间。
而二分法却能使递归的次数以幂的方式减少,这里a,b的值都可能很大,采用二分法最大只需递归31次。采用动态规划的方法可以记忆下已经算过的数据,所以当处理很多实例后,再计算的
时候是非常快的。
a^b=(a%9907)^b
相当于a%9907代替原来的a
程序代码如下
/*
@Author:administrator
Email:522831180@qq.com
*/
#include <stdio.h>
#include <conio.h>
#include <time.h>
#define M 9907
int a,b;
int res[M]={0};
int deal(int n);
int deal(int n)
{
if(n==1)
return a;
int tmp=deal(n/2);
if(!res[tmp])
res[tmp]=(tmp*tmp)%M;
return (res[tmp]*((n&1)?a:1))%M;
}
int main()
{
//Todo: Add your codes below
int i,j,k;
int T;
//freopen("ti.txt","r",stdin); //ti.txt存放输入的数据,本地测试的时候经常会用到这个函数
//freopen("to.txt","w",stdout); //to.txt存放输出的数据
//clock_t st=clock(); //得到起始的clock数
scanf("%d",&T);
for(i=0;i<T;i++)
{
scanf("%d %d",&a,&b);
a%=M;
if(b==0)
printf("%d",1);
else if(a==0||a==1)
printf("%d",a);
else
printf("%d",deal(b));
if(i<T-1)
printf("/n");
}
//printf("/n:tm:%lfs/n",(clock()-st+0.0)/CLOCKS_PER_SEC);//输出程序的时运行间
return 0;
}
本地测试10000组数据,花时间为0.1s