2011(取余运算,快速幂,找规律)

【题目描述】
已知长度最大为200位的正整数n,请求出2011n的后四位。

【输入】
第一行为一个正整数k,代表有k组数据(k≤200),接下来的k行,每行都有一个正整数n,n的位数≤200。

【输出】
每一个n的结果为一个整数占一行,若不足4位,去除高位多余的0。

【输入样例】
3
5
28
792
【输出样例】
1051
81
5521
题目分析:
一看到题目就知道这必须要写一个快速幂,但次数最高是200位,超了long long 肯定是要用字符数组来储存。题目要求给出后四位数字,这就会想到%10000.因为当模上任何数,最终结果肯定小于被模数,这和进制转换有点类似。既然都%10000了,肯定是有一个规律的,至于为何有规律,我也想不明白,总是感觉不可能随着次数的增加结果会一直变化吧。
那么现在的问题就是怎么找这个规律,所以我就在想啊,可不可以让一个数不断的乘2011,再不断的%10000,只要找到最后结果和2011%10000结果一样的数就可以证明这是一个自带周期的数列。
找规律的代码如下:

int a=1,b=1;
    while(1)
    {
        a*=2011;
        a%=10000;
        if(b!=1&&a==2011){
            cout<<b;
            break;}
        b++;
    }

最后结果是501,可知每500个数结果一循环。
所以只需看这次数的最后三位即可。因为500一循环,所以大于500的数都可以减500.
代码:

#include<iostream>
#include<cstring>
using namespace std;
int power(int a,int b)
{
    if(b==0) return 1;
    int temp=power(a,b/2)%10000;
    temp=(temp*temp)%10000;
    if(b%2==1)
        temp*=a%10000;
    return temp%10000;
}
int main()
{
    int t,e=1;
    char n[201];
    cin>>t;
    while(t--)
    {
        cin>>n;
        e=1;
        int len=strlen(n),shu=0;
        if(len>3)
        {
         for(int i=len-1;i>=len-3;i--)
         {
             shu+=(n[i]-'0')*e;
             e*=10;
         }
         if(shu>500) shu-=500;
        }
        if(len<=3)
         for(int i=len-1;i>=0;i--)
        {
            shu+=(n[i]-'0')*e;
            e*=10;
        }
        cout<<power(2011,shu)%10000<<endl;
    }
    return 0;
}
发布了42 篇原创文章 · 获赞 42 · 访问量 9320

猜你喜欢

转载自blog.csdn.net/amazingee/article/details/104272107