Google Code Jam Notes - Rational Number Tree - Java
2013-12-28 00:08
429 查看
Problem:
Retrieved from: http://code.google.com/codejam/contest/2924486/dashboard#s=p1
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.
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.
If the problem id is 1, then output one line containing "
the case number (starting from 1), and
respectively.
If the problem id is 2, then output one line containing "
the case number (starting from 1), and
Analysis:
The trick is to map the Rational Number Tree to another complete binary tree as:
1
10 11
100 101 110 111
You can see in this tree, left child is to append 0 the end of parent node, right child is to append 1 to the parent node. And each binary number value just represents the position:(1, 10(2), 11(3), 100(4), 101(5)..)
Then, since left child is p/(p+q), right child is (p+q)/q, so:
1. when p/q is given, if p >q, it is the left child (0), if p<q, it is the right child (1). Also we can calculate their parent's value. By calculating this repeatedly, until we get the root child 1/1, we can get a successive binary numbers, their value is the
position.
2. when position is given. we can convert this value to binary representation, then we can generate the p/q step by step according to the complete binary tree we built.
Time complexity: O(log(n)).
My solution: (Your opinion is highly appreciated)
Retrieved from: http://code.google.com/codejam/contest/2924486/dashboard#s=p1
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. T test cases follow. Each test case consists of one line. The line contains a problem id (1 or 2) and oneor 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.
Output
For each test case:If the problem id is 1, then output one line containing "
Case #x: p q", where
xis
the case number (starting from 1), and
p,
qare numerator and denominator of the asked array element,
respectively.
If the problem id is 2, then output one line containing "
Case #x: n", where
xis
the case number (starting from 1), and
nis 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 |
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 |
The trick is to map the Rational Number Tree to another complete binary tree as:
1
10 11
100 101 110 111
You can see in this tree, left child is to append 0 the end of parent node, right child is to append 1 to the parent node. And each binary number value just represents the position:(1, 10(2), 11(3), 100(4), 101(5)..)
Then, since left child is p/(p+q), right child is (p+q)/q, so:
1. when p/q is given, if p >q, it is the left child (0), if p<q, it is the right child (1). Also we can calculate their parent's value. By calculating this repeatedly, until we get the root child 1/1, we can get a successive binary numbers, their value is the
position.
2. when position is given. we can convert this value to binary representation, then we can generate the p/q step by step according to the complete binary tree we built.
Time complexity: O(log(n)).
My solution: (Your opinion is highly appreciated)
package codeJam.google.com; import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.math.BigInteger; /** * @author Zhenyi 2013 Dec 21, 2013 17:56:56 PM */ public class RationalNumberTree { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new FileReader( "C:/Users/Zhenyi/Downloads/B-small-practice.in")); FileWriter out = new FileWriter( "C:/Users/Zhenyi/Downloads/B-small-practice.out"); // BufferedReader in = new BufferedReader(new FileReader( // "C:/Users/Zhenyi/Downloads/B-large-practice.in")); // FileWriter out = new FileWriter( // "C:/Users/Zhenyi/Downloads/B-large-practice.out"); Integer T = new Integer(in.readLine()); for (int cases = 1; cases <= T; cases++) { String[] st = in.readLine().split("\\s"); Integer choice = new Integer(st[0]); if (choice.equals(1)) { // find p, q BigInteger n = new BigInteger(st[1]); BigInteger p = new BigInteger("1"); BigInteger q = new BigInteger("1"); int len = 0; BigInteger[] bits = new BigInteger[65]; while (!n.equals(new BigInteger("0"))) { bits[len] = n.mod(new BigInteger("2")); n = n.divide(new BigInteger("2")); len++; } if (len == 1) { out.write("Case #" + cases + ": 1 1" + "\n"); } else { for (int i = len - 2; i >= 0; i--) { if (bits[i].equals(new BigInteger("0"))) { q = q.add(p); } if (bits[i].equals(new BigInteger("1"))) { p = p.add(q); } } out.write("Case #" + cases + ": " + p + " " + q + "\n"); } } else { // find sequence BigInteger n = new BigInteger("0"); BigInteger p = new BigInteger(st[1]); BigInteger q = new BigInteger(st[2]); BigInteger root = new BigInteger("1"); BigInteger[] bits = new BigInteger[65]; int len = 0; while (!(p.equals(root) && q.equals(root))) { if (p.subtract(q).signum() > 0) { // right child bits[len] = new BigInteger("1"); p = p.subtract(q); } else { // left child bits[len] = new BigInteger("0"); q = q.subtract(p); } len++; } bits[len] = new BigInteger("1"); len++; if (len == 1) { out.write("Case #" + cases + ": 1" + "\n"); } else { for (int i = len - 1; i >= 0; i--) { n = n.multiply(new BigInteger("2")).add(bits[i]); } out.write("Case #" + cases + ": " + n + "\n"); } } } in.close(); out.flush(); out.close(); } }
相关文章推荐
- Google Code Jam Notes - Read Phone Number - Java
- Google Code Jam Notes - Good Luck - Java
- Google Code Jam Notes - Sudoku Checker - Java
- Google Code Jam Notes - Moist - Java
- Google Code Jam Notes - Minimum Scalar Product - Java
- Google Code Jam Notes - Dragon Maze - Java
- Google Code Jam Notes - Meet And Party - Java
- Google Code Jam Notes - File Fix-It - Java
- Google Code Jam Notes - Store Credit - Java
- Google Code Jam Notes - Cross The Maze - Java
- Google Code Jam Notes - Spaceship Defence - Java
- Google Code Jam Notes - Captain Hammer - Java
- Google Code Jam Notes - Sorting - Java
- Google Code Jam Notes - Rotate - Java
- Google Code Jam Notes - Bad Horse - Java
- Google Code Jam Notes - All Your Base - Java
- Google Code Jam Notes - Alien Language - Java
- Google Code Jam Notes - Rope Intranet - Java
- Google Code Jam Notes - Reverse Words - Java
- Google Code Jam 2014 Round 1 A:Problem B. Full Binary Tree