Google China New Grad Test 2014 Round A Problem B

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

解题思路:这题太遗憾了。匆忙之中提交大数据,结果发现数据超出long范围,尽快用BigInteger改写,刚好超过了提交时间。也是一道水题,找出推导的方法,递归求解就可以了。

	BigInteger findPQ(BigInteger p, BigInteger q) {
		if (p.equals(new BigInteger("1")) && q.equals(new BigInteger("1")))
			return new BigInteger("1");
		if (p.compareTo(q) < 0)
			return findPQ(p, q.subtract(p)).multiply(new BigInteger("2"));
		else
			return findPQ(p.subtract(q), q).multiply(new BigInteger("2")).add(new BigInteger("1"));
	}

	BigInteger[] findN(BigInteger n) {
		BigInteger[] ret = new BigInteger[2];
		if (n.intValue() == 1) {
			ret[0] = new BigInteger("1");
			ret[1] = new BigInteger("1");
			return ret;
		}
		BigInteger p = n.divide(new BigInteger("2"));
		BigInteger[] pr = findN(p);
		if (n.equals(p.multiply(new BigInteger("2")))) {
			// left
			ret[0] = pr[0];
			ret[1] = pr[0].add(pr[1]);
			return ret;
		} else {
			// right
			ret[0] = pr[0].add(pr[1]);
			ret[1] = pr[1];
			return ret;
		}

	}

	void run() {
		int tests = sc.nextInt();
		for (int test = 1; test <= tests; test++) {
			int id = sc.nextInt();
			System.out.print(String.format("Case #%d:", test));
			if (id == 1) {
				BigInteger n = new BigInteger(sc.next());
				for (BigInteger i : findN(n)) {
					System.out.print(" " + i);
				}
				System.out.println();
			} else {
				BigInteger p = new BigInteger(sc.next());
				BigInteger q = new BigInteger(sc.next());
				BigInteger res = findPQ(p, q);
				System.out.println(" " + res);
			}
		}
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值