2018第一次训练

5385: 树的遍历 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 22            Accepted:16

Description

 

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

Input

 

输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

Output

 

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

Sample Input

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output

 4 1 6 3 5 7 2

如题意所述,我们可以直接得到其前序遍历结果,所以hash一下就好了,特别大了而且成链就写一个大数吧,hash一下就好的

#include <bits/stdc++.h>
using namespace std;
map<int,int>M;
int s[31],c[31],l;
void la(int l,int r,int st,int ed,int f)
{
    if(l<=r&&st<=ed)
    {
        M[f]=c[ed];
        for(int i=l; i<=r; i++)
            if(c[ed]==s[i])
            {
                la(l,i-1,st,st+i-1-l,2*f+1),la(i+1,r,st+i-l,ed-1,2*f+2);
                return ;
            }
    }
}
int main()
{
    cin>>l;
    for(int i=0;i<l;i++)cin>>c[i];
    for(int i=0;i<l;i++)cin>>s[i];
    la(0,l-1,0,l-1,0);
    int f=0;
    for(auto X:M)
    {
        if(f)cout<<" ";
        cout<<X.second,f=1;
    }
    return 0;
}

taozi的队列代码

#include<bits/stdc++.h>
using namespace std;

int post[1000],in[1000],Left[1000],Right[1000];
int n;
int build(int L1,int R1,int L2,int R2)
{
    if(L1>R1)return 0;
    int root=post[R1];
    int pos=L2;
    while(in[pos]!=root)pos++;
    int cnt=pos-L2;
    Left[root]=build(L1,L1+cnt-1,L2,pos-1);
    Right[root]=build(L1+cnt,R1-1,pos+1,R2);
    return root;
}
void level()
{
    queue<int>q;
    q.push(post[n]);
    int f=0;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        if(!f)printf("%d",u),f=1;
        else printf(" %d",u);
        if(Left[u])q.push(Left[u]);
        if(Right[u])q.push(Right[u]);
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>post[i];
    for(int i=1;i<=n;i++)
        cin>>in[i];
    build(1,n,1,n);
    level();
    return 0;
}

5445: 中位数 分享至QQ空间

时间限制(普通/Java):2000MS/6000MS     内存限制:250000KByte
总提交: 15            测试通过:2

描述

 

给定两个序列,都已经从小到大排序,求两个序列合并后的中位数。

所谓中位数是指:当排序后的序列元素个数是奇数时取中间值,否则去中间两个数的平均数。

你能想出O(log(m+n))复杂度的算法吗?

输入

 

多组数据。每组数据的:

第一行为两个整数n和m,(1<=n, m<=10000000)。

第二行由n个从小到大排序的整数。

第三行由m个从小到大排序的整数。

以EOF结束。

输出

 

输出中位数,保留2位小数。

样例输入

 

2 1
1 3
2
2 2
1 2
3 4

样例输出

 

提示

因本题输入数据规模较大,请使用类似以下代码输入一个整数(输入挂):

int Scan()

{

    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负

        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数

        res = ch - '0';

    while((ch = getchar()) >= '0' && ch <= '9' )

        res = res * 10 + ch - '0';

    return flag ? -res : res;

}

 枚举pos看他是第几个数,当然也会相等,所以这个还是特判一下的

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
int a[N],b[N],n,m;
long long L,R,zws;
int la()
{
    while(L<=R)
    {
        int mi=(L+R)>>1;
        int pos=upper_bound(a,a+n,b[mi])-a;
        //cout<<mi<<" "<<pos<<" "<<mi+pos+1<<"\n";
        if(a[pos-1]==b[mi])
        {
            if(mi+pos==zws)return mi;
        }
        if(mi+pos+1<zws)
        {
            if(mi==m-1)return -1;
            L=mi+1;
        }
        else if(mi+pos+1>zws)
        {
            if(mi==0)return -1;
            R=mi-1;
        }
        else  //cout<<"*"<<mi<<"\n";
        {
            return mi;
        }
    }
    //cout<<"b not in a";
    return -1;
}
int lb()
{
    while(L<=R)
    {
        int mi=(L+R)>>1;
        int pos=upper_bound(b,b+m,a[mi])-b;
        if(b[pos-1]==a[mi])
        {
            if(mi+pos==zws)
                return mi;
        }
        if(mi+pos+1<zws)
        {
            if(mi==n-1)return -1;
            L=mi+1;
        }
        else if(mi+pos+1>zws)
        {
            if(mi==0)return -1;
            R=mi-1;
        }
        else //cout<<"#"<<mi<<"\n";
        {
            return mi;
        }
    }
    //cout<<"a not in b";
    return -1;
}
int Scan()
{

    int res = 0, ch, flag = 0;
    if((ch = getchar()) == '-')             //判断正负

        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数

        res = ch - '0';

    while((ch = getchar()) >= '0' && ch <= '9' )

        res = res * 10 + ch - '0';

    return flag ? -res : res;

}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0; i<n; i++)a[i]=Scan();
        for(int i=0; i<m; i++)b[i]=Scan();
        L=0,R=m-1,zws=(n+m+1)/2;
        int t=la();
        if(t==-1)
            L=0,R=n-1,t=lb(),t=a[t];
        else t=b[t];
        //cout<<t<<"\n";
        if((n+m)%2==0)
        {
            zws++;
            L=0,R=m-1;
            int t1=la();
            if(t1==-1)
                L=0,R=n-1,t1=lb(),t1=a[t1];
            else t1=b[t1];
            t+=t1;
        }
        else t+=t;
        printf("%.2f\n",t/2.);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/BobHuang/p/8980104.html