POJ 1930 Dead Fraction 数论

别人说这是小学奥数水平的题目,orz,作者受到了极大的打击。

如果是用笔写的话相信很多人都能将循环小数化成分数。

来个例子吧:0.333.....怎么化成分数呢?

设 x = 0.333......

10x = 3.33......

10x - x = 3

9x = 3

x = 1 / 3

和这个思路类似,对于一般情况,我们可以推导出一个公式(推导出了公式才方便编程)。

引用别人博客的一张图片(顺便引用原作者的一句话:这图片很不美观):http://blog.csdn.net/xinghongduo/article/details/6231107

POJ 1930 Dead Fraction 数论_第1张图片

相信读者看了一遍就会了吧。下面是ac代码:

#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long int ll;
const int MAX_SIZE = 20;
const int INF = 0x3f3f3f3f;

int GCD(int x, int y)
{
    return !y ? x : GCD(y, x % y);
}

// 快速幂
int pow(int a, int n)
{
    int res = 1;
    while (n)
    {
        if (n & 1)
            res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}

int main()
{
    //freopen("test.txt", "r", stdin);

    char str[MAX_SIZE];
    while (~scanf("%s", str) && strcmp(str, "0"))
    {
        int all = 0, cnt1 = 0;  // all代表abcdefg,cnt1代表all的位数,也就是k + c。
        for (unsigned i = 2; i < strlen(str) - 3; i++, cnt1++)
            all = all * 10 + str[i] - '0';
        int mina = INF, minb = INF;
        for (int num = all / 10, cnt2 = cnt1 - 1; cnt2 >= 0; num /= 10, cnt2--)  // num代表abcd,cnt2代表num的位数,也就是c。
        {
            int a = all - num, b = pow(10, cnt2) * (pow(10, cnt1 - cnt2) - 1);
            int g = GCD(a, b);
            if (b / g < minb)
            {
                minb = b / g;
                mina = a / g;
            }
        }
        printf("%d/%d\n", mina, minb);
    }
    return 0;
}


你可能感兴趣的:(ACM-数论)