zoukankan      html  css  js  c++  java
  • 【7001】n阶法雷序列

    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
         对任意给定的一个自然数n(n<=100),将分母小于等于n的不可约的真分数按上升的次序排序,并且在第一个分数前加上0/1,而在最后一个分数后加上1/1,这个序列称为n阶法雷序列,以Fn表示。例如,F8为:
         0/1、1/8、1/7、1/6、1/5、1/4、2/7、1/3、3/8、2/5、3/7、1/2、4/7、3/5、5/8、2/3、5/7、3/4、4/5、5/6、6/7、7/8、1/1。
        编程求出n阶法雷序列,每行输出10个分数。

    Input

        输入为一个正整数n

    Output

        输出若干行,每行10个分式。(每个分式用空格隔开,为简化输出,每行的最后一个分式后也有一个空格,最后用换行结束)

    Sample Input

        8
    

    Sample Output

    0/1 1/8 1/7 1/6 1/5 1/4 2/7 1/3 3/8 2/5 
    3/7 1/2 4/7 3/5 5/8 2/3 5/7 3/4 4/5 5/6 
    6/7 7/8 1/1 
    
     

    【题解】

    真分数可以根据两个数是否互质来判断,或者换个说法,两个数的最大公因数是否为1,如果为1就互质。然后用一个结构来存储 分数的分子和分母,这里同时还要存储这个分数的小数形式。因为我们要根据小数来排序。在排序的时候,把整个结构都交换。在排序之前再加入一个0/1 1/1到数组里就好。两个数互质就加入这个结构数组。
    【代码】

    #include <cstdio>
    
    struct fln
    
    {
        int fs[2];
        double xs;
    };
    
    int n,num = 0;
    fln bb[20000];
    
    
    int gcd(int a,int b) //获取两个数的最大公因数
    {
        if (b == 0)
            return a;
                else
                    return gcd(b,a % b);
    
    }
    
    void input_data()
    {
        scanf("%d",&n);
    }
    
    void get_ans()
    {
        for (int i = 1;i <= n;i++)
            for (int j = i+1;j <= n;j++) //获取i和j 即i/j ,其中i < j,且i,j互质
                if (gcd(i,j) == 1)
                    {
                        num++;
                        bb[num].fs[0] = i; //fs代表分数
                        bb[num].fs[1] = j;
                        double aa = (double) i;
                        double cc = (double) j;
                        double temp = aa / cc;
                        bb[num].xs = temp; //记录小数
                    }
        bb[++num].fs[0] = 0;  //把 0/1 和 1/1加入数组中.
        bb[num].fs[1] = 1;
        bb[num].xs =0.0;
        bb[++num].fs[0] = 1;
        bb[num].fs[1] = 1;
        bb[num].xs = 1.0;
    }
    
    void kp(int l,int r) //以小数作为元素 进行快排。
    {
        int i = l,j = r;double m = bb[(i+j)/2].xs;
        do
        {
            while (bb[i].xs < m) i++;
            while (m < bb[j].xs) j--;
            if (i <= j)
                {
                    int m; //要整个交换 这一段可以写成 fln m m = bb[i];bb[i] = bb[j];bb[j] = m,这样会短很多.
                    m = bb[i].fs[0];bb[i].fs[0] = bb[j].fs[0];bb[j].fs[0] = m;
                    m = bb[i].fs[1];bb[i].fs[1] = bb[j].fs[1];bb[j].fs[1] = m;
                    double tt;
                    tt = bb[i].xs;bb[i].xs = bb[j].xs;bb[j].xs = tt;
                    i++;j--;
                }
        }
        while (i <= j);
        if (l < j) kp(l,j);
        if (i < r) kp (i,r);
    }
    
    
    
    
    void output_ans()
    {
        int m = 0;
        for (int i = 1;i <= num;i++) //控制一下输出
        {
            printf("%d/%d ",bb[i].fs[0],bb[i].fs[1]);
            m++;
            if (m == 10)
                {
                    printf("
    ");
                    m = 0;
                }
        }
    }
    
    int main()
    {
        input_data();
        get_ans();
        kp(1,num);
        output_ans();
        return 0;
    }
    


     

  • 相关阅读:
    HTML引入文件的绝对路径、相对路径、根目录
    测试脚本中的等待方法:
    MVC、MTV、FBV、CBV、母版和继承:
    多窗口处理周杰伦:
    登录测试函数版:
    登录测试:
    hibernate配置详情1(hibernate.cfg.xml)
    常用数据库连接串与驱动总结
    常用数据库连接串与驱动总结
    常用数据库连接串与驱动总结
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632449.html
Copyright © 2011-2022 走看看