1. 程式人生 > 其它 >【Go 語言社群】POJ 1047 Round and Round We Go 迴圈數新解

【Go 語言社群】POJ 1047 Round and Round We Go 迴圈數新解

題目描述:

給定一字串表示的高精度數,判斷它是否是可迴圈的。如果假設字串num的長為n,則將num從1開始乘到n,如果每次得到的結果包含的字元元素都和a是相同的,則它是可迴圈的。

解題思路:

初看這一題,想到的解法是利用高精度數的乘,計算出num乘以1到n的結果,再與num進行對比。這種方法較為簡單,可以得到正確的結果,但是效率並不是很理想。對於迴圈數,我們最常見到的是迴圈小數,而這一題的解法也是由此引申得出的。

初等數論裡面有以下三個定理:

尤拉定理:設a、m為整數,m>1,(a,m)=1,則a^φ(m)≡1 (mod m)。 整數的次數:a、m為整數,m>1,(a,m)=1,k是使a^k≡1 (mod m)成立的最小正整數,則k叫做a對模m的次數。 次數定理:設a對模m的次數為k,n是滿足a^n≡1 (mod m)的正整數,則k|n。

這三個定理的證明在數論書裡面都有介紹,想詳細瞭解的可以自己去查閱。利用上面的定理有:

1/7=0.142857142857...

迴圈節的位數為6,將上式乘以10^6得

=>10^6/7=142857.142857142857...

=>(10^6-1)/7=142857

=>999999/7=142857

對於其他的數num,如果其位數是n,如果num*(n+1)得到的結果是n個9,那麼這個數就是可迴圈的。

#include<iostream>

#include<string>

using namespace std;



int main()

{

        string num;

        bool flag = true;

        int i, n, c, t;

        while(cin >> num)

        {

                flag = true;

                n = num.size() + 1;

                c = 0; t = 0;

                for(i = n - 2; i >= 0; i--)

                {

                        t = num[i] - '0';

                        if((t * n + c) % 10 != 9)  //判斷結果是否全為9

                        {

                                flag = false;

                                break;

                        }

                        c = (t * n + c) / 10;

                }



                if(flag)

                {

                        cout << num << " is cyclic" << endl; 

                }

                else

                {

                        cout << num << " is not cyclic" << endl;

                }

        }

        return 0;

}