ACdream1187(简单找规律)

C - Problem C

Time Limit:  2000/1000MS (Java/Others)  Memory Limit:  128000/64000KB (Java/Others)
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:

  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(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:

  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.

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:

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

题意:RT

思路:规律很明显,递归往上求解即可,这题要用unsigned long long,结果我比赛的时候用long long,被这个坑到了,深刻的记下了

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         using namespace std; typedef unsigned long long ll; vector 
        
          dfs(ll n) { vector 
         
           q(2,0); if(n==1){ q[0]=q[1]=1; return q; } q=dfs(n/2); ll a; ll b; if(n%2==0){ a=q[0]; b=q[0]+q[1]; } else { a=q[0]+q[1]; b=q[1]; } q[0]=a; q[1]=b; return q; } ll dfs2(ll a,ll b) { if(a==1&&b==1)return 1; ll n; if(a>b){ n=dfs2(a-b,b); n=n*2+1; } else { n=dfs2(a,b-a); n=n*2; } return n; } int main() { int t,tt=0; scanf("%d",&t); while(t--) { int vis; ll n,p,q; scanf("%d",&vis); if(vis==1){ cin>>n; vector 
          
            q(2,0); q=dfs(n); printf("Case #%d: ",++tt); cout< 
           
             <<' '< 
            
              < 
             
               >p>>q; printf("Case #%d: ",++tt); cout< 
              
                < 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值