首页 > 代码库 > [NOIP2005] 普及组 循环

[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 }  

 

[NOIP2005] 普及组 循环