POJ 2499 Binary Tree(二叉树,找规律)

题意:给一个这样的二叉树,每个节点用一对数(a,b)表示,根节点为(1,1)。设父亲为(a,b),左儿子(a+b,b),右儿子(a,a+b)。
  给几组数据,(i,j),求从根节点到(i,j)节点需要向左子树走多少次,往右子树多少次。
思路:可以发现:当i>j时,(i,j)为左儿子;当i<j时,(i,j)为右儿子。
    设父节点为(a,b),往左子树需要走l次,往右子树需要走r次,那么:
    1.i>j时:i=a+b,j=b -> a=i-j,b=j l++;
    2.i<j时:i=a,j=a+b -> a=i,b=j-i r++;

当然,写代码时不能一个一个减,会超时的。一次性把能减的都减去。

 

#include <iostream>
#include <stdio.h>
/*
AC
给一个这样的二叉树,每个节点用一对数(a,b)表示,根节点为(1,1)。设父亲为(a,b),左儿子(a+b,b),右儿子(a,a+b)。
给几组数据,(i,j),求从根节点到(i,j)节点需要向左子树走多少次,往右子树多少次。
思路:可以发现:当i>j时,(i,j)为左儿子;当i<j时,(i,j)为右儿子。
    设父节点为(a,b),往左子树需要走l次,往右子树需要走r次,那么:
    1.i>j时:i=a+b,j=b -> a=i-j,b=j l++;
    2.i<j时:i=a,j=a+b -> a=i,b=j-i r++;

*/
using namespace std;

int main()
{
    int t;
    scanf("%d",&t);
    long long i,j;
    int l,r;
    for(int w=1;w<=t;w++){
        l=0;r=0;
        scanf("%lld%lld",&i,&j);
        while(1){
            if(i==1 && j==1)
                break;
            /*
            若i>j,只要求i中有多少个j,即i/j,l+=i/j,最后再把i剩下的赋值给i
            若i<j,只要求j中有多少个i,即j/i,r+=j/i,最后再把j剩下的赋值给j
            */
            if(i>j){
                l+=i/j;
                i-=i/j*j;
                //若i是j的倍数,即当j=1时,l要减去1,退出循环
                //也可以上面l+=(i-1)/j,这样就不用讨论i=0的情况了。
                if(i==0){
                    l--;
                    break;
                }
            }
            else{
                r+=j/i;
                j-=j/i*i;
                //若j是i的倍数,即当i=1时,r要减去1,退出循环
                //也可以上面r+=(j-1)/i,这样就不用讨论j=0的情况了。
                if(j==0){
                    r--;
                    break;
                }
            }
        }
        printf("Scenario #%d:\n",w);
        printf("%d %d\n",l,r);
        puts("");
    }
    return 0;
}

 

 

posted @ 2013-10-02 12:14  辰曦~文若  阅读(451)  评论(0编辑  收藏  举报