题目:http://noi.openjudge.cn/ch0204/2991/
- 总时间限制:1000ms 内存限制: 65536kB
- 描述
- 已知长度最大为200位的正整数n,请求出2011^n的后四位。
- 输入
-
第一行为一个正整数k,代表有k组数据,k<=200接下来的k行,
每行都有一个正整数n,n的位数<=200 - 输出
- 每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0
- 样例输入
-
3 5 28 792
- 样例输出
-
1051 81 5521
参考:
利用循环节:http://m.blog.csdn.net/u013675643/article/details/51820648
高精度除法:http://blog.csdn.net/qq_35479641/article/details/51810945
下面的思路参照循环节的做法。
题目只需要输出后四位,因此答案必然有一个最多5位数的循环节。于是可以先写个暴力去找循环节,发现循环节长度为500,这个数就很好处理了。后面读入n时只保留后三位数,再mod500就得出答案了,比写高精度简单多了~
1 #include<stdio.h> 2 #include<string.h> 3 // m^n % k 4 long long quickpow(long long m,long long n,long long k) 5 { 6 long long ans = 1; 7 while (n > 0) 8 { 9 if (n & 1) 10 ans = (ans*m)%k; 11 n = n >> 1 ; 12 m = (m*m)%k; 13 } 14 return ans; 15 } 16 int main(int argc, char *argv[]) 17 { 18 int k; 19 int i; 20 char n[205]; 21 int N,len; 22 scanf("%d",&k); 23 for(i=0;i<k;i++) 24 { 25 scanf("%s",n);getchar(); 26 N=0; 27 len=strlen(n); 28 N=n[len-1]-'0'; 29 if(len>=2) N=(n[len-2]-'0')*10+N; 30 if(len>=3) N=(n[len-3]-'0')*100+N; 31 if(len>=4) N=(n[len-4]-'0')*1000+N; 32 N=N%500; 33 printf("%lld\n",quickpow(2011,N,10000)); 34 } 35 return 0; 36 }
还有一个数学论证:http://blog.csdn.net/li744831579/article/details/8784547