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

来源:互联网 发布:金十数据vip版 免费 编辑:程序博客网 时间:2024/06/18 13:56

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, T. 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:

  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 p, q 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 ≤ n, p, q ≤ 216-1; p/q is an element in a tree with level number ≤ 16.

Large dataset

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

Sample


Input 
 
Output 
 
41 22 1 21 52 3 2
Case #1: 1 2Case #2: 2Case #3: 3 2Case #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 longint 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