问题 E: 有理数树------------------------------------思维(递归+模拟)

题目描述
十九世纪的时候,Moriz Stern (1858)与Achille Brocot (1860)发明了“一棵树”。据说,经由一些简单的规则而产生的这一棵树上,可以包含零以上所有的有理数。这棵树看起来大致这样:
在这里插入图片描述

你观察出规则了吗?
首先,他们在第一列放两个“分数”,第一个是0 / 1,代表0;第二个是1 / 0,代表无穷大。接着他们一列一列地产生这棵树,当他们要产生第k+1列的时候,就先把前k列所有的分数按照大小排成一列(假设有n个),在这些数之间会有n - 1个间隔,那么第k + 1列就准备产生n - 1个数,其值的分子恰好是左右两个数的分子的和、分母是左右两个数的分母的和。
例如,2 / 3,而它的2就是左边1 / 2的1和右边1 / 1的分子1相加的结果;而2 / 3的3,则是1 / 2的2加上1 / 1的分母1而得。
从这棵树中,我们可以看出,每个正的最简分数在这棵树中恰好出现一次,我们用字母“L”和“R”分别表示从树根(1 / 1)开始的一步“往左走”和“往右走”,则每一个数都可以由L和R组成的序列表示。
例如,LRRL表示从1 / 1开始往左走一步到1 / 2,然后往右走到2 / 3,再往右走到3 / 4,最后往左走到5 / 7。我们可以把LRRL看作5 / 7的一种表示法。几乎每个正分数均有唯一的方法表示成一个由L和R组成的序列。
给定一个分数,输出它的LR表示法。

输入
输入有两个互素的正整数m和n(1 ≤ n,m ≤1000)。
输出
输出对应的LR表示法。
样例输入 Copy
5 7
样例输出 Copy
LRRL

解析:

性质:二叉排序树 左子树小于根 右子树大于根

根据上面性质模拟。把分子分母,左边的分子分母,右边的分子分母全部存到结构体,然后递归处理

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e5+10000;
struct node
{
    int l1,l2,r1,r2,fz,fm;
}a[N];
string s;
void dfs(int i)
{
    double x=(a[i].fz*1.0/a[i].fm*1.0);
    double y=(n*1.0/m*1.0);
    if(y<x)
    {
        a[i+1].fz=a[i].l1+a[i].fz;
        a[i+1].fm=a[i].l2+a[i].fm;
        a[i+1].l1=a[i].l1;
        a[i+1].l2=a[i].l2;
        a[i+1].r1=a[i].fz;
        a[i+1].r2=a[i].fm;
        s+='L';
        dfs(i+1);
    }
    else if(y>x)
    {
        a[i+1].fz=a[i].fz+a[i].r1;
        a[i+1].fm=a[i].fm+a[i].r2;
        a[i+1].l1=a[i].fz;
        a[i+1].l2=a[i].fm;
        a[i+1].r1=a[i].r1;
        a[i+1].r2=a[i].r2;
        s+='R';
        dfs(i+1);
    }
     
}
int main()
{
    scanf("%d %d",&n,&m);
    a[0].l1=0;a[0].l2=1;a[0].r1=1;a[0].r2=0;a[0].fz=1;a[0].fm=1;
    dfs(0);
    cout<<s<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值