2011的n次方
Posted 寄蜉蝣于天地,渺沧海之一粟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2011的n次方相关的知识,希望对你有一定的参考价值。
题目: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 }
暴力寻找循环节的一个简单操作:
1 #include <stdio.h> 2 3 long long quickpow(long long m,long long n,long long k)//返回m^n % k的结果 4 { 5 long long ans = 1; 6 while (n > 0) 7 { 8 if (n & 1) 9 ans = (ans*m)%k; 10 n = n >> 1 ; 11 m = (m*m)%k; 12 } 13 return ans; 14 } 15 int main(int argc, char *argv[]) 16 { 17 freopen("data.txt","w",stdout); 18 int A[10005],B[10005]; 19 for(int i=1;i<10005;i++) 20 { 21 //printf("%d\\n",quickpow(2011,i,10000)); 22 A[i]=quickpow(2011,i,10000); 23 } 24 25 for(int i=1;i<10005;i++) 26 { 27 for(int j=i+1;j<10005;j++) 28 { 29 if(A[i]==A[j]) { B[i]=j;break; } 30 } 31 } 32 for(int i=1;i<10005;i++) 33 { 34 printf("%d %d\\n",A[i],B[i]); 35 } 36 return 0; 37 }
还有一个数学论证:http://blog.csdn.net/li744831579/article/details/8784547
以上是关于2011的n次方的主要内容,如果未能解决你的问题,请参考以下文章