1. 程式人生 > >Binary Tree(偽二叉樹)

Binary Tree(偽二叉樹)

right div bin esc nta i++ bsp repr 相減

Description

Background
Binary trees are a common data structure in computer science. In this problem we will look at an infinite binary tree where the nodes contain a pair of integers. The tree is constructed like this:
  • The root contains the pair (1, 1).
  • If a node contains (a, b) then its left child contains (a + b, b) and its right child (a, a + b)

Problem
Given the contents (a, b) of some node of the binary tree described above, suppose you are walking from the root of the tree to the given node along the shortest possible path. Can you find out how often you have to go to a left child and how often to a right child?

Input

The first line contains the number of scenarios.
Every scenario consists of a single line containing two integers i and j (1 <= i, j <= 2*10 9
) that represent
a node (i, j). You can assume that this is a valid node in the binary tree described above.

Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing two numbers l and r separated by a single space, where l is how often you have to go left and r is how often you have to go right when traversing the tree from the root to the node given in the input. Print an empty line after every scenario.

Sample Input

3
42 1
3 4
17 73

Sample Output

Scenario #1:
41 0

Scenario #2:
2 1

Scenario #3:
4 6
題目意思:當時一看題目確實被嚇到了,以為真的是數據結構中的二叉樹,畢竟作為一個萌新acmer,真真被唬住了。
看了看樣例其實和二叉樹沒有太大關系,我們知道二叉樹的根節點是(1,1),題目給一個(l,r)求其回到(1,1)
向左向右轉的次數。
解題思路:我們先來考慮一下(l,r)的來源,因為r!=l,若l>r,那麽(l,r)來自於(l-r,r)向左轉;若r>l,
那麽(l,r)來自於(l,r-l)向右轉。那麽可以通過遞推的不斷相減得到以下的代碼:
 1 #include<stdio.h>
 2 #include<string.h>
 3 int main()
 4 {
 5     int t;
 6     long long a,b,m,n,lcount,rcount,i;
 7     scanf("%d",&t);
 8     i=1;
 9     while(t--)
10     {
11         scanf("%lld%lld",&a,&b);
12         lcount=0;
13         rcount=0;
14         while(1)
15         {
16             if(a>b)
17             {
18                 a=a-b;
19                 lcount++;
20             }
21             if(b>a)
22             {
23                 b=b-a;
24                 rcount++;
25             }
26             if(b==1&&a==1)
27                 break;
28         }
29         printf("Scenario #%lld:\n",i++);
30         printf("%lld %lld\n\n",lcount,rcount);
31     }
32     return 0;
33 }

很不幸的是交上之後直接時間超限,再看看題 two integers i and j (1 <= i, j <= 2*10 9),都達到了數億的數量級,顯然會造成數億次的常數

運算,那麽就需要換換思路了,我參考了一下網上大佬們的算法,運用除法來代替減法實現加速運算,這種思路其實在之前的某些題目中

運用過。

上代碼:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int main()
 4 {
 5     int t;
 6     long long a,b,c,m,n,lcount,rcount,i;
 7     scanf("%d",&t);
 8     i=1;
 9     while(t--)
10     {
11         scanf("%lld%lld",&a,&b);
12         lcount=0;
13         rcount=0;
14         while(1)
15         {
16             if(a>b)
17             {
18                 c=a/b;
19                 a=a%b;///當b==1時,有可能造成a==0
20                 if(a==0)///此時需要調成結果
21                 {
22                     c--;
23                     a=1;
24                 }
25                 lcount=lcount+c;
26             }
27             if(b>a)
28             {
29                c=b/a;
30                b=b%a;
31                if(b==0)
32                {
33                    c--;
34                    b=1;
35                }
36                rcount=rcount+c;
37 
38             }
39             if(b==1&&a==1)
40                 break;
41         }
42         printf("Scenario #%lld:\n",i++);
43         printf("%lld %lld\n\n",lcount,rcount);
44     }
45     return 0;
46 }

不得不感慨,還是得學習啊。

 

Binary Tree(偽二叉樹)