您的位置:首页 > 其它

ACdream 1187 Rational Number Tree(搜索:DFS)

2014-08-29 21:23 411 查看


Rational Number Tree

Time Limit: 2000/1000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others)

SubmitStatisticNext
Problem


Problem 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



Source

codejam


Manager

KIDx

SubmitStatistic

一看还以为是数学题,推理了好久公式...

后来才想到一共不才64层么,根据p q的关系直接dfs不就行了么


但是这个题有个坑,一直到比赛结束都没A掉,比赛一结束立马就A了。。。

原因是题目数据可能会爆long long,所以要用unsigned long long

但是因为我用的printf(%lld),所以一直WA

正确的姿势是用printf(%llu),比赛结束后抱着试一试的心态用cout试了下然后就A了。。。

后来再改回printf(%llu)也对了

0ms代码如下:

#include <bits/stdc++.h>
#define LL unsigned long long
using namespace std;

struct Node {
LL p, q;
}node;

Node get_pq(LL n) {
Node tmp, ans;
if(n == 1ll) {
ans.p = 1ll;
ans.q = 1ll;
}
else {
LL x = n>>1;
tmp = get_pq(x);
if(n % 2 == 1ll) {
ans.p = tmp.p+tmp.q;
ans.q = tmp.q;
} else {
ans.p = tmp.p;
ans.q = tmp.p+tmp.q;
}
}
return ans;
}

LL get_n(LL p, LL q) {
if(p == 1ll) return 1ll<<(q-1ll);
if(q == 1ll) return (1ll<<p)-1ll;
if(p < q) {
return 2ll*get_n(p, q-p);
} else {
return 2ll*get_n(p-q, q)+1ll;
}
}

int main(void) {
Node ans;
int T, id;
LL n, p, q;
scanf("%d", &T);
for(int t=1; t<=T; ++t) {
scanf("%d", &id);
printf("Case #%d: ", t);
if(id == 1) {
scanf("%llu", &n);
ans = get_pq(n);
printf("%llu %llu\n", ans.p, ans.q);
} else {
scanf("%llu%llu", &p, &q);
printf("%llu\n", get_n(p, q));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: