Round A China New Grad Test 2014---很基本的一道题Problem B. Rational Number Tree

Problem

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:

  1. 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.
  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, TT 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:

  1. 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.
  2. 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.

Output

For each test case:

  1. 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 pq are numerator and denominator of the asked array element, respectively.
  2. 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.

Limits

1 ≤ T ≤ 100; p and q are relatively prime.

Small dataset

1 ≤ npq ≤ 216-1; p/q is an element in a tree with level number ≤ 16.

Large dataset

1 ≤ npq ≤ 264-1; p/q is an element in a tree with level number ≤ 64.

Sample


Input 
 

Output 
 
4
1 2
2 1 2
1 5
2 3 2
Case #1: 1 2
Case #2: 2
Case #3: 3 2
Case #4: 5

我的解题思路:(注意数据范围,我用到了unsigned long long)

就是一颗满二叉树,向左走为0向右走记为1,然后对于输入n时建立这样一棵树,对于输入p,q时也建立这样一棵树。最后根据这棵树来求解。

输入n时:

若n==1则停止

否则,若n为偶数0入栈,并把n除以2赋值给n;

若n为奇数1入栈,并把n-1除以2赋值给n。

这样就得到了一个01串,然后再根据01串求解:

若栈不空

则栈顶为0:a=a;b=a+b;

栈顶为1:a=a+b;b=b;

 

输入p,q时:

若p==q则结束

否则:若p>q,1入栈,p=p-q;

若p<q,0入栈,q=q-p;

这样也得到了一个01串

根据01串求出n

若栈不为空:

0时n=n*2;

1时n=n*2+1;

最终我的代码:(Google不看你的代码只看结果所以代码没有优化)

(由于Google不考虑时间复杂性一开始我用的递归,呵呵结果一到大数据就太慢了,后来又改成了迭代)

#include<iostream>
#include<vector>
#include<queue>
#include<math.h>
#include<stack>
using namespace std;
#define ll unsigned long long
int main()
{
	
	freopen("D:\\B-large-practice.in","r",stdin);
	freopen("D:\\B-large-practice.out","w",stdout);
	/***********************************************/
	int T;
	cin>>T;
	int id=1;
	while(T--)
	{
		int type;
		ll n,p,q;
		cin>>type;
		if(type==1)
		{
			ll a,b,temp;
			int i;
			cin>>n;
			temp=n;
			stack<int> zhan;
            while(temp/2>0)
			{
				if(temp%2==0){
				zhan.push(0);
				temp=temp/2;
				}else 
				{
			    zhan.push(1);
				temp=(temp-1)/2;
				}
			}
			a=1;
			b=1;
			while(zhan.size()>0)
			{
				if(zhan.top()==0)
				{
					a=a;
					b=b+a;
				}else 
				{
					a=a+b;
					b=b;
				}
				zhan.pop();
			}
			cout<<"Case #"<<id<<": "<<a<<" "<<b<<endl;
		}
		else 
		{
			ll rn=1;
			stack<int> zhan;
			cin>>p>>q;
			while(p!=q)
			{
				if(p<q)
				{
					zhan.push(0);
					q=q-p;
				}
				else if(p>q)
				{
					zhan.push(1);
					p=p-q;
				}
			}
			while(zhan.size()>0)
			{
				if(zhan.top()==1)  
            		rn=rn*2+1;
				else rn=rn*2;
				zhan.pop();
			}
			cout<<"Case #"<<id<<": "<<rn<<endl;
		}

		id++;
	}
	/**********************************************/
	fclose(stdin);
	fclose(stdout);
	return 0;
}


 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值