题意:一个二叉树,根节点为(1,1),左孩子为(a+b,b),右孩子为(a , a+b),给出一个区间(i,j),让你求一条最短的路中经过几个左孩子,几个右孩子。
解题过程:刚开始的时候,画出树来开出有规律,但是没想出来要逆序推,一直从上到下找规律,结果怎么也找不到,后来参考了别人的思路,才知道要从下往上推。
题目中已经给出规律了,任意一个左孩子区间,左边数总小于右边数,任意右孩子,左边数总大于右边数。即如果i<j,则该节点属于左孩子,i>j,则该节点属于右孩子,然后从(i,j)推到(1,1),记录左右节点数。由于数据很大,要用除法计算,还要注意一点是:如果i%j==0,那么i=1.
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <math.h> using namespace std ; typedef long long ll ; int main() { int cas , left , right ; ll a , b ; int c = 1 ; scanf ( "%d" , &cas ); while ( cas-- ) { cin>>a>>b ; left = 0 ; right = 0 ; while ( a != 1 || b != 1 ) { if ( a > b ) { int tem = a / b ; if ( a % b == 0 ) { left += ( tem - 1 ); a = 1 ; } else { left += tem ; a = a % b ; } } else if ( a < b ) { int tem = b / a ; if ( b % a == 0 ) { right += ( tem - 1 ); b = 1 ; } else { right += tem ; b = b % a ; } } } printf ( "Scenario #%d:\n%d %d\n\n" , c++ , left , right ); } return 0 ; }