分數樹(BZOJ2651)

2651: 分數樹

時間限制: 1 Sec  內存限制: 128 MB
提交: 16  解決: 15
[提交][狀態][我的提交]

題目描述

一種生成形如m/n(m和n互質)分數的方法是從兩個最初的分數開始,然後重複以下的操作任意多次:
    把新生成的分數插入到原來的分數之間。

例如,第1次將在生成1個新分數,得到

第2次得到2個新分數:

第3次得到4個新分數:

接下來將得到8個、16個、……新分數。整個生成分數的過程是一棵二叉樹:

在這棵樹上,某個分數的位置是固定且唯一的。不可能在兩個位置上出現同一個分數。如果把看成這棵樹的根,L表示向左走,R表示向右走,那麼一個由L和R組成的字符串將對應一個唯一的分數。例如LRRL表示從向左走到,再向右走到,再向右走到,再向左走到,則可以把LRRL作爲的唯一的標識。

每一個正分數均對應一個由L和R組成的字符串作爲其唯一的標識。於是你的任務就是對於給定的任意一個最簡分數,找出其唯一的標識。

輸入

第1行:2個正整數m和n,分別表示分子和分母。m與n互質,且m和n不同時等於1,m和n不超過10000

輸出

1 個由L和R組成的字符串,表示分數的唯一標識

樣例輸入

 (如果複製到控制檯無換行,可以先粘貼到文本編輯器,再複製)

5 7

樣例輸出

LRRL
分析:根據“觀察法”,任意一個節點的左兒子小於它,右兒子大於它(qwq找規律大法好23333333),然後二分就可以了23333。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
using namespace std;
struct node{
	int mol,den;
	node(){}
	node(int a,int b){
		mol=a,den=b;
	}
	bool operator == (const node &x)const{
		return mol==x.mol&&den==x.den;
	}
	bool operator < (const node &x)const{
		if(!x.den)	return 1;
		if(!den)	return 0;
		int a=mol*x.den,b=x.mol*den;
		return a<b;
	}
}tmp;
int m,n;
node creat(node a,node b){
	return node(a.mol+b.mol,a.den+b.den);
}
void divide(node l,node r){
	node mid=creat(l,r);
	if(tmp==mid)	return ;
	else if(tmp<mid)	putchar('L'),divide(l,mid);
	else	putchar('R'),divide(mid,r);
}
int main(){
    scanf("%d %d",&m,&n),tmp=node(m,n);
	divide(node(0,1),node(1,0));
    return 0;
}


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