分數與小數的相互轉換

小數轉化爲分數

 

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1717

 

題意:把小數轉化爲分數,循環部分用()表示。


void Work(char str[])  
{  
    int len = strlen(str);  
    LL a = 0;  
    LL b = 0;  
    int cnt1 = 0;  
    int cnt2 = 0;  
    for(int i=2;i<len;i++)  
    {  
        if(str[i] == '(') break;  
        a = a * 10 + str[i] - '0';  
        cnt1++;  
    }  
    bool flag = false;  
    for(int i=2;i<len;i++)  
    {  
        if(str[i] == '(' || str[i] == ')')  
        {  
            flag = true;  
            continue;  
        }  
        b = b * 10 + str[i] - '0';  
        cnt2++;  
    }  
    cnt2 -= cnt1;  
    LL p = b - a;  
    LL q = 0;  
    if(!flag)  
    {  
        p = b;  
        q = 1;  
        cnt2 = 0;  
    }  
    for(int i=0;i<cnt2;i++)  
        q = q * 10 + 9;  
    for(int i=0;i<cnt1;i++)  
        q = q * 10;  
    LL g = gcd(p,q);  
    p /= g;  
    q /= g;  
    cout<<p<<"/"<<q<<endl;  
}  



 

分數轉化爲小數

 

題目:http://acm.hdu.edu.cn/showproblem.php?pid=2522

 

定理1:有理數a/b (其中0<a<b,(a,b)=1)能表示成純循環小數的充要條件是(b,10)=1

定理2:有理數a/b, 0<a<b, (a,b)=1,b=(2^α)*(5^β)*b1, (b1,10)=1,b1不等於1,α,β不全爲零,則a/b可以表示爲純

     循環小數,其不循環的位數爲u = max(α,β)

定理1的證明參見  薛利敏的論文  純循環小數循環節的規律

定理2的證明:通過把b拆成2部分,(10^u)*b1,當然分子a要相應乘以(2^(u-α))*(5^(u-β))即爲a'=a*(2^(u-α))*(5^(u-β)),這樣對於a'/b1先化成真分數,大於1的部分就是不循環小數部分,小於1的是純循環小數部分,得證。

 

void Work(int n)  
{  
    bool flag = 0;  
    int ans[N],f[N];  
    memset(ans,0,sizeof(ans));  
    memset(f,0,sizeof(f));  
    if(n < 0)  
    {  
        n = -n;  
        flag = 1;  
    }  
    int k = 1;  
    f[k] = 1;  
    int cnt = 0;  
    while(k && n != 1)  
    {  
        k *= 10;  
        ans[cnt++] = k / n;  
        k %= n;  
        if(f[k]) break;  
        f[k] = 1;  
    }  
    if(flag) printf("-");  
    if(n == 1) puts("1");  
    else  
    {  
        printf("0.");  
        for(int i=0;i<cnt;i++)  
            printf("%d",ans[i]);  
        puts("");  
    }  
}  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章