• ACM学习历程——HDU4814 Golden Radio Base(数学递推) (12年成都区域赛)


    Description

    Golden ratio base (GRB) is a non-integer positional numeral system that uses the golden ratio (the irrational number (1+√5)/2 ≈ 1.61803399 symbolized by the Greek letter φ) as its base. It is sometimes referred to as base-φ, golden mean base, phi-base, or, phi-nary.       
    Any non-negative real number can be represented as a base-φ numeral using only the digits 0 and 1, and avoiding the digit sequence "11" � this is called a standard form. A base-φ numeral that includes the digit sequence "11" can always be rewritten in standard form, using the algebraic properties of the base φ ― most notably that φ + 1 = φ 2 . For instance, 11(φ) = 100(φ). Despite using an irrational number base, when using standard form, all on-negative integers have a unique representation as a terminating (finite) base-φ expansion. The set of numbers which possess a finite base-φ representation is the ring Z[1 + √5/2]; it plays the same role in this numeral systems as dyadic rationals play in binary numbers, providing a possibility to multiply.       
    Other numbers have standard representations in base-φ, with rational numbers having recurring representations. These representations are unique, except that numbers (mentioned above) with a terminating expansion also have a non-terminating expansion, as they do in base-10; for example, 1=0.99999….       
    Coach MMM, an Computer Science Professor who is also addicted to Mathematics, is extremely interested in GRB and now ask you for help to write a converter which, given an integer N in base-10, outputs its corresponding form in base-φ.      
                  

    Input

    There are multiple test cases. Each line of the input consists of one positive integer which is not larger than 10^9. The number of test cases is less than 10000. Input is terminated by end-of-file.      
                  

    Output

    For each test case, output the required answer in a single line. Note that trailing 0s after the decimal point should be wiped. Please see the samples for more details.      
                  

    Sample Input

    1 2 3 6 10
                  

    Sample Output

    1 10.01 100.01 1010.0001 10100.0101

    Hint

     
     
    由于φ + 1 = φ 2,两边同乘φ k,得到φ k+1+φ k=φ k+2,说明只有有两位是1,就往前进一位。此外由φ + 1 = φ 2推到的2φ 2=φ 3+1,同理可知:φ k+3+φ k=2φ k+2,说明每一位的2都可以,由它前一位和它的后两位的1构成,这样就能将所有大于2的数降成1.再配合之前的,反复模拟便可得。由于当场没有估算这个数的长度,所以采用两个数组分别存了整数部分和小数部分。整体效率不是非常高,但是在短时间内做出来还是很高兴的。
     
     
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #define inf 0x3fffffff
    #define esp 1e-10
    #define N 100
    
    using namespace std;
    
    int z[N], x[N], lenz, lenx;
    
    bool judge ()
    {
        if(z[0] && x[0])
            return 0;
        for (int i = 0; i < lenx; ++i)
            if (x[i] > 1 || (x[i] && x[i+1]))
                return 0;
    
        for (int i = 0; i < lenz; ++i)
            if (z[i] > 1 ||(z[i] ==1 && z[i+1] == 1))
                return 0;
    
        return 1;
    }
    
    void doz (int i)
    {
        if (i == lenz-1)
            lenz++;
        int up = z[i] / 2;
        z[i] = z[i] & 1;
        z[i+1] += up;
        if (i >= 2)
            z[i-2] += up;
        else
        {
            if (lenx < 3 - i)
                lenx = 3 - i;
            x[1-i] += up;
        }
    }
    
    void dox (int i)
    {
        if (i+3 > lenx)
            lenx = i + 3;
        int up = x[i] / 2;
        x[i] = x[i] & 1;
        x[i+2] += up;
        if (i == 0)
            z[0] += up;
        else
            x[i-1] += up;
    }
    
    void qt (int n)
    {
        memset (z, 0, sizeof(z));
        memset (x, 0, sizeof(x));
        lenz = 1;
        lenx = 0;
        z[0] = n;
        while (!judge ())
        {
            for (int i = lenx-1; i >= 0; --i)
            {
    
                if (i == 0 && x[i] > 0 && x[i+1] > 0)
                {
                    int up = min (x[i], x[i+1]);
                    z[0] += up;
                    x[0] -= up;
                    x[1] -= up;
                    continue;
                }
                else if (x[i] > 0 && x[i+1] > 0)
                {
                    int up = min (x[i], x[i+1]);
                    x[i-1] += up;
                    x[i+1] -= up;
                    x[i] -= up;
                    continue;
                }
                if (x[i] > 1)
                {
                    dox (i);
                    continue;
                }
    
    
            }
            while(x[lenx-1] == 0)
                lenx--;
            for (int i = 0; i < lenz; ++i)
            {
    
                if (i == 0 && z[i] > 0 && x[0] > 0)
                {
                    if (i == lenz-1)
                        lenz++;
                    int up = min (z[i], x[0]);
                    z[1] += up;
                    z[0] -= up;
                    x[0] -= up;
                    continue;
                }
                else if (z[i] > 0 && z[i+1] > 0)
                {
                    if (i+3 > lenz)
                        lenz = i + 3;
                    int up = min (z[i], z[i+1]);
                    z[i+2] += up;
                    z[i+1] -= up;
                    z[i] -= up;
                    continue;
                }
                if (z[i] > 1)
                {
                    doz(i);
                    continue;
                }
            }
        }
        while(x[lenx-1] == 0)
            lenx--;
    }
    
    int main()
    {
        //freopen ("test.txt", "r", stdin);
        int n;
        while (scanf ("%d", &n) != EOF)
        {
            qt (n);
            for (int i = lenz - 1; i >= 0; --i)
                printf ("%d", z[i]);
            if (lenx > 0)
                printf (".");
            for (int i = 0; i < lenx; ++i)
                printf ("%d", x[i]);
            printf ("
    ");
        }
        return 0;
    }
    
     
  • 相关阅读:
    对List实现分页
    笔记2022.05.26
    mybatis 时区设置成UTC后time不能用字符串进行比较
    SAP笔记abap 跳过SAP Access Key 方法
    LOOP GROUP BY 分组循环的使用方法小栗子
    SAP小技巧 双LOOP循环的性能优化
    SAP Shared Memory Objects在不同会话不同ABAP程序中传输数据示例
    转:abap中 跨session传递数据export database
    SQL server 把多条记录查找结果合并成一条记录 L
    linux 实现cp命令递归复制
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4046563.html
Copyright © 2020-2023  润新知