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

    说明

    对于30%的数据,k <= 4;

    对于全部的数据,k <= 100。

    NOIP2005普及组第四题

    依照题意累乘,设原数是n,假设乘了x次后,最后一位(第L位)的数与最开始相同了,那么就要开始计算倒数第二位(L-1位)的循环节。

    由于L位至少要乘x次才能循环,所以算L-1位时,至少要乘n^x次才能让L位再重复(L-1位循环而L位不同是没有意义的)。

    以此类推,每找到一层循环,在找下一层时就可以每次直接乘n^x^y^...,运行效率会高很多。

    具体实现要用到高精度。

    这代码估计是高精乘法常数写挂了,用时近1000ms

     1 #include<iostream>  
     2 #include<cstring>  
     3 #include<cmath>  
     4 #include<cstdio>  
     5 using namespace std;  
     6 int t=1;  
     7 unsigned int n=0,k;
     8 unsigned int xh[200];
     9 int num;//记录有多少层
    10 char s[200];
    11 bool flag=0,flag2=0;
    12 struct node{  
    13     unsigned int v[200];  
    14     int s;  
    15 }a,b,c,bas,ans,nn;
    16 node multiple(const node a1,const node b1){ //高精度乘法部分   
    17     int i,j,x=0;  
    18     if(a1.s==1&&a1.v[0]==0)return a1;  
    19     if(b1.s==1&&b1.v[0]==0)return b1;    
    20     node c1={0};  
    21     for(i=0;i<=100 && i<a1.s;i++){  
    22         for(j=0;j<=100 && j<b1.s;j++){  
    23             c1.v[i+j]+=a1.v[i]*b1.v[j];  
    24             c1.v[i+j+1]+=c1.v[i+j]/10;  
    25             c1.v[i+j]%=10;  
    26         }  
    27         c1.s=i+j;  
    28         if(c1.v[i+j]!=0)c1.s++;  
    29     }  
    30     if(c1.s>k) c1.s=k+1;  
    31     return c1;  
    32 } 
    33 
    34 int main(){  
    35     int i,j;  
    36     scanf("%s%d",s,&k);
    37     c.s=strlen(s);
    38     ans.v[0]=1;
    39     ans.s=1;
    40     for(i=0;i<c.s;i++) c.v[i]=s[c.s-i-1]-'0'; 
    41     bas=c;//原数备份,用作比较 
    42     a=c;
    43     b=c; 
    44     int k1;
    45     for(k1=0;k1<k;k1++){
    46         num=0;
    47         b=bas;
    48 //        c=bas;
    49         do{
    50             b=multiple(a,b);
    51             num++;
    52         }while(num<10 && b.v[k1]!=bas.v[k1]);
    53         if(bas.v[k1]!=b.v[k1]){
    54             printf("-1");
    55             return 0;
    56         }
    57         b=a;
    58         for(j=0;j<num-1;j++)
    59              a=multiple(a,b);
    60          
    61         nn.s=1;
    62         nn.v[0]=num;
    63         ans=multiple(ans,nn);
    64     }
    65     i=100;
    66     while(ans.v[i]==0)i--;
    67     for( ;i>=0;i--)printf("%d",ans.v[i]);
    68     return 0;  
    69 }  
  • 相关阅读:
    [省选联考 2020 A 卷] 组合数问题
    [HAOI2018]苹果树
    [集训队作业2013]城市规划
    多项式牛顿迭代
    多项式开方
    分治 FFT 模板的三种过法
    Graham 求静态凸包
    exp 初探
    HAOI2018 染色
    如何关闭wps热点,如何关闭wpscenter,如何关闭我的wps
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6004782.html
Copyright © 2011-2022 走看看