九度oj 1078,1113,1176 二叉树

1078题目:

http://ac.jobdu.com/problem.php?pid=1078


大意是,告诉你前序遍历和中序遍历求后序遍历。

大致思路,通过前序遍历我们可以很容易知道这个二叉树的根节点知道,之后根据中序遍历,我们可以知道那些节点是左子树,哪些节点是右子树。

递归得解:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stack>
#include <queue>
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
 
using namespace std;
char cpre[30];
char cmed[30];
int med[30];
int len;
void theMedInthePre(){//计算中序遍历下的每个字符在前序输出中的对应的位置
    len=strlen(cpre);
    int k=0;
   for(int i=0;i<len;i++){
     for(int j=0;j<len;j++){
        if(cmed[j]==cpre[i]){
           med[j]=k;
           k++;
           break;
        }
     }
   }
//   cout<<"----------------------------\n"<<endl;
}
void post(int left,int right){
   if(right<left)
     return ;
   if(right==left){
     cout<<cmed[left];
     return ;
     }
    int min=30;
    int point=30;
    for(int i=left;i<=right;i++){
       if(med[i]<min){
         min=med[i];
         point=i;
       }
    }
    post(left,point-1);
    post(point+1,right);
    cout<<cmed[point];
}
 
int main(){
  while(scanf("%s%s",cpre,cmed)!=EOF){
     theMedInthePre();
     post(0,len-1);
     cout<<endl;
  }
 
}
 
/**************************************************************
    Problem: 1078
    User: zhouyudut
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/


1113题目:

http://ac.jobdu.com/problem.php?pid=1113

我的大致思路是,先求出这个两个点之间的高度,再进行计算。

虽然,思路很清晰,但是在实际编写过程中,总是WA。

究其原因,边界情况未考虑。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stack>
#include <queue>
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
 
using namespace std;
int length;//从n到m之间树的高度
long long int theLeftLeft;
long long int theRightRight;
void theLegnthOfLevel(long long int n,long long int m)//计算n到m之间树的高度
{
    length=0;
    long long int theUp=1;
    long long int tempn=n;
    while(tempn/2>0){
      theUp++;
      tempn/=2;
    }
    while(pow(2,theUp-1)<=m){
        length++;
        theUp++;
    }
}
void theNum(long long int n,long long int m){
  theLeftLeft=n;
  theRightRight=n;
  for(int i=1;i<length;i++){
    theLeftLeft=theLeftLeft<<1;
    theRightRight=(theLeftLeft<<1)-1;
  //  cout<<"theLeftLeft="<<theLeftLeft<<endl;
 //   cout<<"theRightRIght="<<theRightRight<<endl;
  }
  long long int num;
  num=pow(2,length-1)-1;
//  cout<<"length="<<length<<endl;
 // cout<<"num="<<num<<endl;
  if(theLeftLeft<=m && theRightRight>=m)
  {
      num+=m-theLeftLeft+1;
  }else if(theRightRight<m){
      num+=theRightRight-theLeftLeft+1;
  }
  cout<<num<<endl;
}
int main(){
   long long int n,m;
   while(1){
     scanf("%lld%lld",&n,&m);
     if(n==0 && m==0)
       return 0;
       theLegnthOfLevel(n,m);
       theNum(n,m);
   }
}
 
/**************************************************************
    Problem: 1113
    User: zhouyudut
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1608 kb
****************************************************************/

1176题目:

http://ac.jobdu.com/problem.php?pid=1176

还是那个问题,考虑不周全。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stack>
#include <queue>
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
 
using namespace std;
int arr[1010];
int length;
int seek;
int main(){
   while(scanf("%d",&length)!=EOF){
     for(int i=1;i<=length;i++)
      cin>>arr[i];
     cin>>seek;
     int left=pow(2,seek-1);
     int right=pow(2,seek)-1;
     if(left>length){
     cout<<"EMPTY"<<endl;
     continue;
     }
     if(length<right)
     {
         right=length;
     }
        for(int i=left;i<right;i++){
            cout<<arr[i]<<' ';
        }
        cout<<arr[right]<<endl;
 
 
   }
}
 
/**************************************************************
    Problem: 1176
    User: zhouyudut
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1612 kb
****************************************************************/

求一个数的二进制的非符号位的最高位的1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值