5385: 树的遍历
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: 中位数
总提交: 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; }