SDNU 1117.循环 高精度数 思维

1117.循环

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


众所周知,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位都相同。


Input

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


Output

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


Sample Input

32 2


Sample Output

4


    题意很明确,就是去算一个数一直相乘是否能构成一个循环节,数据范围量比较大,所以直接用JAVA写的,因为数据量很大,所以直接跑暴力是肯定不可以的,需要一点技巧。我们可以对这个数的每一位依次进行处理,先处理最后一位(取余10),然后去跑循环,之后得到最后一位的循环节长度,然后使最后一位不变(也就是乘他之前一位循环的那个数),因为是对每一位进行的处理,所以最大也就是循环10个数,如果大于10就说明不存在循环节,直接输出-1就可以了。

    举个实际的数来说,比如说对于789,3这一组数据,先对个位的9处理得到循环节为2

    (789^1)mod1000=789

    (789^2)mod1000=521

    然后再处理十位的时候就可以直接用521这个数来乘,就能保证个位的数值不发生变化

    (789*(521^1))mod1000=69

    (789*(521^2))mod1000=949

    (789*(521^3))mod1000=429

    (789*(521^4))mod1000=509

    (789*(521^5))mod1000=189

    此时就能找到一个循环节,然后处理百位的时候用(521^5)mod1000=601再来乘,保证十位的数值不发生变化

    (789*(601^1))mod1000=189

    (789*(601^2))mod1000=589

    (789*(601^3))mod1000=989

    (789*(601^4))mod1000=389

    (789*(601^5))mod1000=789

    这样所有位就都处理完了,然后再去将每一位的循环节乘起来,也就是2*5*5=50,所以789末3位的循环节就是50。

    因为一开始写了个暴力,所以用的JAVA,后来改的时候干脆直接用暴力程序改了。

    下面AC代码:

import java.math.BigDecimal;  
import java.util.Scanner;

public class Main {
	static BigDecimal mod;
	static BigDecimal mod2;
	static BigDecimal zero=new BigDecimal(0);
	static BigDecimal one=new BigDecimal(1);
	static BigDecimal two=new BigDecimal(2);
	
	static BigDecimal qpow(BigDecimal a,BigDecimal b)  
	{  
		BigDecimal ans;
	    ans=one;
	    a=a.remainder(mod2);
	    //System.out.println("mod = " + mod);
	    while(b.compareTo(zero)>0)
	    {  
	    	if((b.remainder(two)).compareTo(one)==0)
	    	{
	    		ans=(ans.multiply(a)).remainder(mod2);  
	        }  
	    	b=b.divideToIntegralValue(two);
	    	a=(a.multiply(a)).remainder(mod2);
	    }  
	    return ans;  
	}  
	
	public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        BigDecimal n,k;
        BigDecimal t,temp;
        BigDecimal a;
        BigDecimal g;
        BigDecimal ans;
        //BigDecimal i;
        //BigDecimal one=new BigDecimal(1);
        BigDecimal ten=new BigDecimal(10);
        int flag2;
        //System.out.println(1);
        while(cin.hasNext()) 
        {
        	ans=one;
        	mod=one;
        	mod2=one;
        	flag2=1;
            n=cin.nextBigDecimal();
            k=cin.nextBigDecimal();
            //System.out.println(qpow(n,k));
            //BigDecimal mod=new BigDecimal(1);
            BigDecimal i=new BigDecimal(0);  
            BigDecimal len=new BigDecimal(1);
            g=n;
            t=n;
            for(;i.compareTo(k)<0;i=i.add(one))
            	mod2=mod2.multiply(ten);
            for(i=zero;i.compareTo(k)<0;i=i.add(one))
            { 
            	//System.out.println(i + "---------");
            	mod=mod.multiply(ten);
            	//t=qpow(g,len);
            	if(i.compareTo(zero)==0||i.compareTo(one)==0)
            		t=g;
            	else
            		t=qpow(t,len);
            	temp=n.remainder(mod);
	            //System.out.println("mod = " + mod);
	            //System.out.println("g = " + g + " len = " + len + " t = " + t);
	            len=zero;
	            a=n.multiply(t);
	            while(flag2==1)
	            {
	            	len=len.add(one);
	            	//System.out.println("len = " + len + " a = " + a + " a.mod = " + a.remainder(mod));
	            	if((a.remainder(mod)).compareTo(temp)==0)
	            	{
	            		break;
	            	}
	            	if(len.compareTo(ten)>0)
	            	{
	            		flag2=0;
	            	}
	            	g=a.remainder(mod2);
	            	a=a.multiply(t);
	            }
	            //if(len.compareTo(zero)==0)
	            	//len=one;
	            ans=ans.multiply(len);
	            if(flag2==0)
	            	break;
            }
            if(flag2==1)
            	System.out.println(ans);
            else
            	System.out.println(-1);
        }
	}
}


你可能感兴趣的:(SDNU)