1. 程式人生 > >題解 P1050 【循環】

題解 P1050 【循環】

如果 次方 個數字 循環節 空間 div 數據 大小 高精度乘法

**題意分析**: 1.求整數n(1 <= n < $10^{100}$)的後k位的循環節 2.數據規模:1 <= n < $10^{100}$,k <= 100 **算法分析:** 直接枚舉:用高精度乘法計算n的a次方,直到後k位出現循環,這樣做有2個缺點:(1)時間復雜度過大,a的大小無法判斷,可能會很超過MAXN,所以會超時 (2)無法判斷不出現循環的情況 可以發現,如果後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位 因為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位,這與前式矛盾, 所以我們可以求出後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個數字中某個數開始的而不包括應該循環的那一位,那麽意味著該循環的一位永遠不會循環.那麽這個時候就可以判斷,這個數不會出現循環 這樣做,上面直接枚舉的2個問題都可以有效解決, **優化**: 因為高精度計算中,計算後k位只需要保存後k位乘積的結果,而k範圍較小,在計算是若判斷大於k位則跳出,這樣,節約了一定時間,同時也可以節約空間(因為結果只需存k位). 如果10次中已經出現循環的數,則可以退出 框架: for(int k=0;k<n;k++)//枚舉循環的位數k for(int j=0;j<10;j++)//每一位最多有10種可能 { a*=p;//做乘法,p是待乘的倍數 a1*=p;//a1記錄下一次的增加的倍數 If(a[k]=s[k])//若第k位產生循環 { sign=1;//標記產生循環 sol[total++]=j+1;//記錄k位循環節長度是後k-1的循環節的多少倍 p=a;//改變乘數 break; } }

題解 P1050 【循環】