zoukankan      html  css  js  c++  java
  • 循环

    NOIP2005普及组第四题,

    题目描述

    乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。

    众所周知,2的正整数次幂最后一位数总是不断的在重复2,4,8,6,2,4,8,6……我们说2的正整数次幂最后一位的循环长度是4(实际上4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:

    循环 循环长度

    2 2、4、8、6

    4

    3 3、9、7、1

    4

    4 4、6 2

    5 5 1

    6 6 1

    7 7、9、3、1

    4

    8 8、4、2、6

    4

    9 9、1 2

    这时乐乐的问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数n的正整数次幂来说,它的后k位是否会发生循环?如果循环的话,循环长度是多少呢?

    注意:

    1. 如果n的某个正整数次幂的位数不足k,那么不足的高位看做是0。

    2. 如果循环长度是L,那么说明对于任意的正整数a,n的a次幂和a + L次幂的最后k位都相同。

    输入输出格式

    输入格式:

    输入文件circle.in只有一行,包含两个整数n(1 <= n < 10^100)和k(1 <= k <= 100),n和k之间用一个空格隔开,表示要求n的正整数次幂的最后k位的循环长度。

    输出格式:

    输出文件circle.out包括一行,这一行只包含一个整数,表示循环长度。如果循环不存在,输出-1。

    输入输出样例

    输入样例#1:
    32 2
    输出样例#1:
    4
    算法分析

    可以发现,如果后k位循环,那么循环节一定是后k-1位循环的循环节的倍数

    >   证明如下:设后k位循环节为a1,后k-1位循环的循环节是a2,且a1=p*a2+b(p,b是常数)

    >     那么n^1的后k-1位=n^a2的后k-1位

    >      n^1的后k位=n^a1的后k位->n^1的后k-1位=n^a1的后k-1位

    >      所以n^a2的后k-1位等于n^a1的后k-1位...................................[1]

    >       因为b不是循环节,所以n^(p*a2)的后k-1位不等于n^(p*a2+b)的后k-1位

    >        n^(p*a2)的后k-1位等于n^a2的后k-1位

    >                所以n^a2的后k-1位不等于n^a1的后k-1位,这与[1]矛盾,

    >     所以我们可以求出后k-1位的循环节,再将后k-1位的循环节作为乘数求后k位的循环节(若n^a后k-1位与n的后k-1位相等,那么n^(a-1)为求后k位时的乘数),这样可以保证所枚举到的数一定是后k-1为循环节的倍数,而且可以大大减少枚举的数量

    >     可以通过记录后k位循环节长度是后k-1的循环节的多少倍来求循环节,这样,枚举的数就不需要用高精度,最后结果相乘时用高精度

    >   (2)整数的每一位有10种可能,如果某个长度枚举10次仍然没有循环的话,根据抽屉原理,因为这10个数中有1个没取到(就是该循环的一位)那么就一定出现了重复,也就是产生循环,但这个循环是以这9个数字中某个数开始的而不包括应该循环的那一位,那么意味着该循环的一位永远不会循环.那么这个时候就可以判断,这个数不会出现循环

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    int k,kk;
    struct date{
    int x[10005];
    friend void read(date&a){
    char s[10005];
    int i,j;
    cin>>s;
    for(i=0;s[i];i++);
    for(i--,j=0;i>=0;i--,j++)a.x[j]=s[i]-'0';
    }
    date operator*(date&b){
    date c;
    for(int i=0;i<k;i++)for(int j=0;i+j<k;j++)
    c.x[i+j]+=x[i]*b.x[j];
    for(int i=0;i<k;i++){
    c.x[i+1]+=c.x[i]/10;
    c.x[i]%=10;
    }
    return c;
    }
    date operator*(int&b){
    for(int i=0;i<k;i++)x[i]*=b;
    for(int i=0;i<k;i++){
    x[i+1]+=x[i]/10;
    x[i]%=10;
    }
    return *this;
    }
    bool operator==(date&b){
    for(int i=0;i<=kk;i++)if(x[i]!=b.x[i])return false;
    return true;
    }
    date(){for(int i=0;i<=10005;i++)x[i]=0;}
    }c,s,n,ans;
    int main(){
    int i;
    read(n);
    scanf("%d",&k);
    // ans=s*n;
    // for(i=k;i&&!ans.x[i];i--);
    // for(i;i>=0;i--)printf("%d",ans.x[i]);
    ans.x[0]=1;
    for(kk=0;kk<k;kk++){
    c=n;
    for(i=1;;i++){
    s=c*n;
    if(s==n){n=c;ans=ans*i;break;}
    c=s;
    if(i>10){printf("-1");return 0;}
    }
    }
    for(i=k;i>0&&!ans.x[i];i--);
    for(i;i>=0;i--)printf("%d",ans.x[i]);
    }



  • 相关阅读:
    剑指Offer-11.二进制中1的个数(C++/Java)
    剑指Offer-10.矩形覆盖(C++/Java)
    剑指Offer-9.变态跳台阶(C++/Java)
    UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
    UVA1607 Gates 与非门电路 (二分)
    UVA 1451 Average平均值 (数形结合,斜率优化)
    UVA 1471 Defense Lines 防线 (LIS变形)
    UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
    UVA 11134 FabledRooks 传说中的车 (问题分解)
    UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
  • 原文地址:https://www.cnblogs.com/linzeli/p/7384824.html
Copyright © 2011-2022 走看看