ACdream 1187 ——Rational Number Tree(二进制,递归)
2016-07-18 20:52
387 查看
题目:
Description
Consider an infinite complete binary tree where the root node is 1/1 and left and right childs of node p/q are p/(p+q) and (p+q)/q, respectively. This tree looks like:
It is known that every positive rational number appears exactly once in this tree. A level-order traversal of the tree results in the following array:
Please solve the following two questions:
Find the n-th element of the array, where n starts from 1. For example, for the input 2, the correct output is 1/2.
Given p/q, find its position in the array. As an example, the input 1/2 results in the output 2.
Input
The first line of the input gives the number of test cases, T(1 ≤ T ≤ 100).
T test cases follow. Each test case consists of one line.
The line contains a problem id (1 or 2) and one or two additional integers:
If the problem id is 1, then only one integer n is given, and you are expected to find the n-th element of the array.
If the problem id is 2, then two integers p and q are given, and you are expected to find the position of p/q in the array.
p and q are relatively prime.
1 ≤ n, p, q ≤ 264-1
p/q is an element in a tree with level number ≤ 64.
Output
For each test case:
If the problem id is 1, then output one line containing "Case #x: p q", where x is the case number (starting from 1), and p, q are numerator and denominator of the asked array element, respectively.
If the problem id is 2, then output one line containing "Case #x: n", where x is the case number (starting from 1), and n is the position of the given number.
Sample Input
Sample Output
题意:一棵树,每个节点是一个分数。做查询,通过编号确定分数,通过分数确定编号。
思路:二叉树,编号可以用二进制表示。然后逐步递归回去。两种查询要用不同的递归方法但思路基本一致。注意数据范围。要用llu,或者用cin和cout。
代码如下:
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <string>
using namespace std;
#define MAXN 1e30
#define INF 1e9+7
#define MODE 1000000
unsigned long long a=1,b=1;
void solve_p_q(unsigned long long n)
{
if(n==1){
a=b=1;
}
else if(n&1){
solve_p_q((n-1)>>1);
a=a+b;
}
else{
solve_p_q(n>>1);
b=a+b;
}
}
unsigned long long res=0;
void solve_n(unsigned long long p,unsigned long long q)
{
if(p==q)
res=1;
else if(p>q)
{
solve_n(p-q,q);
res=res*2+1;
}
else{
solve_n(p,q-p);
res=res*2;
}
}
int main()
{
int t;
cin>>t;
int s=1;
for(int s=1;s<=t;s++)
{
int m;
cin>>m;
if(m==1)
{
unsigned long long n;
cin>>n;
solve_p_q(n);
cout<<"Case #"<<s<<": "<<a<<" "<<b<<endl;
}
if(m==2)
{
unsigned long long p,q;
cin>>p>>q;
solve_n(p,q);
printf("Case #%d: ",s);
cout<<res<<endl;
}
}
}
Description
Consider an infinite complete binary tree where the root node is 1/1 and left and right childs of node p/q are p/(p+q) and (p+q)/q, respectively. This tree looks like:
1/1 ______|______ | | 1/2 2/1 ___|___ ___|___ | | | | 1/3 3/2 2/3 3/1 ...
It is known that every positive rational number appears exactly once in this tree. A level-order traversal of the tree results in the following array:
1/1, 1/2, 2/1, 1/3, 3/2, 2/3, 3/1, ...
Please solve the following two questions:
Find the n-th element of the array, where n starts from 1. For example, for the input 2, the correct output is 1/2.
Given p/q, find its position in the array. As an example, the input 1/2 results in the output 2.
Input
The first line of the input gives the number of test cases, T(1 ≤ T ≤ 100).
T test cases follow. Each test case consists of one line.
The line contains a problem id (1 or 2) and one or two additional integers:
If the problem id is 1, then only one integer n is given, and you are expected to find the n-th element of the array.
If the problem id is 2, then two integers p and q are given, and you are expected to find the position of p/q in the array.
p and q are relatively prime.
1 ≤ n, p, q ≤ 264-1
p/q is an element in a tree with level number ≤ 64.
Output
For each test case:
If the problem id is 1, then output one line containing "Case #x: p q", where x is the case number (starting from 1), and p, q are numerator and denominator of the asked array element, respectively.
If the problem id is 2, then output one line containing "Case #x: n", where x is the case number (starting from 1), and n is the position of the given number.
Sample Input
4 1 2 2 1 2 1 5 2 3 2
Sample Output
Case #1: 1 2 Case #2: 2 Case #3: 3 2 Case #4: 5
题意:一棵树,每个节点是一个分数。做查询,通过编号确定分数,通过分数确定编号。
思路:二叉树,编号可以用二进制表示。然后逐步递归回去。两种查询要用不同的递归方法但思路基本一致。注意数据范围。要用llu,或者用cin和cout。
代码如下:
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <string>
using namespace std;
#define MAXN 1e30
#define INF 1e9+7
#define MODE 1000000
unsigned long long a=1,b=1;
void solve_p_q(unsigned long long n)
{
if(n==1){
a=b=1;
}
else if(n&1){
solve_p_q((n-1)>>1);
a=a+b;
}
else{
solve_p_q(n>>1);
b=a+b;
}
}
unsigned long long res=0;
void solve_n(unsigned long long p,unsigned long long q)
{
if(p==q)
res=1;
else if(p>q)
{
solve_n(p-q,q);
res=res*2+1;
}
else{
solve_n(p,q-p);
res=res*2;
}
}
int main()
{
int t;
cin>>t;
int s=1;
for(int s=1;s<=t;s++)
{
int m;
cin>>m;
if(m==1)
{
unsigned long long n;
cin>>n;
solve_p_q(n);
cout<<"Case #"<<s<<": "<<a<<" "<<b<<endl;
}
if(m==2)
{
unsigned long long p,q;
cin>>p>>q;
solve_n(p,q);
printf("Case #%d: ",s);
cout<<res<<endl;
}
}
}
相关文章推荐
- c语言中i++与++i的使用技巧
- DNS小结
- linux 风格的结构体
- 正则表达式(三)
- android动态设置控件大小
- 深入浅出PageRank算法
- 小米、华为手机 为啥都杀入无障碍体验市场?
- LeetCode 162. Find Peak Element
- HDU 5448 Marisa’s Cake
- 利用dockerize模板为容器内应用生成配置文件和环境变量
- codeforces 677D
- 数据结构——二叉树的四种遍历方式(非递归)
- 消息队列mq的原理及实现方法
- 结构体(hdu 1236)
- 包含min函数的栈
- python错误之mission parentheses in call to 'print'
- 大菲波数<hdoj1715>
- 逃离迷宫
- AsyncTask异步任务类
- Java学习一:一些基本的语句