目录
P1827 [USACO3.4]美国血统 American Heritage
今天是致力于刷题的一天!!!
P1827 [USACO3.4]美国血统 American Heritage
题目描述
农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。
你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。 这是在样例输入和 样例输出中的树的图形表达方式:
C
/ \
/ \
B G
/ \ /
A D H
/ \
E F
树的中序遍历是按照左子树,根,右子树的顺序访问节点。
树的前序遍历是按照根,左子树,右子树的顺序访问节点。
树的后序遍历是按照左子树,右子树,根的顺序访问节点。
输入格式
第一行: 树的中序遍历
第二行: 同样的树的前序遍历
输出格式
单独的一行表示该树的后序遍历。
输入输出样例
输入 #1复制
ABEDFCHG CBADEFGH
输出 #1复制
AEFDBHGC
说明/提示
题目翻译来自NOCOW。
USACO Training Section 3.4
思路
1、分别用字符串a,b存储前序和中序
2、设前序的起点与终点是a1,a2-1,中序的起点与终点是b1,b2-1
3、要知道前序遍历(根左右)的第一个结点是根节点
4、所以在中序遍历(左根右)中找到a1,记录其位置为k;k的左边就是左子树。右边就是右子树
5、用n,m存储左右子树结点个数
6、当n>0时即左子树结点个数不为零时,递归;
7、当m>0时即右子树结点个数不为零时,递归;
int n=k-b1;//左子树的结点个数 int m=b2-(k+1);//右子树的节点个数 if(n>0) fun(a1+1,a1+1+n,b1,b1+n); if(m>0) fun(a2-m,a2,k+1,k+1+m); cout<<a[a1];//最后输出根节点(后序遍历,左右根)
代码实现
#include<bits/stdc++.h>
using namespace std;
char a[100],b[100];
void fun(int a1,int a2,int b1,int b2)
{
int k;//用于保存中序遍历中根节点的位置
for(int i=b1;i<b2;i++)
{
if(b[i]==a[a1])
{
k=i;
break;
}
}
int n=k-b1;//左子树的结点个数
int m=b2-(k+1);//右子树的节点个数
if(n>0)
fun(a1+1,a1+1+n,b1,b1+n);
if(m>0)
fun(a2-m,a2,k+1,k+1+m);
cout<<a[a1];//最后输出根节点(后序遍历,左右根)
return;
}
int main()
{
int len;
cin>>b>>a;
len=strlen(a);
//cout<<len;
fun(0,len,0,len);
return 0;
}
P1305 新二叉树
题目描述
输入一串二叉树,输出其前序遍历。
输入格式
第一行为二叉树的节点数 nn。(1 \leq n \leq 261≤n≤26)
后面 nn 行,每一个字母为节点,后两个字母分别为其左右儿子。
空节点用 *
表示
输出格式
二叉树的前序遍历。
输入输出样例
输入 #1复制
6 abc bdi cj* d** i** j**
输出 #1复制
abdicj
思路
刚开始还想着建树,想了半天也觉得这真没法建呀,后来发现他是按顺序输入的二叉树,所以直接递归输出不就行了,还建什么树呀!!!
1、用二维数组把这n对父亲孩子存下来
2、按照前序遍历(根左右),递归输出
if(ch!='*') { cout<<ch;//输出根节点 for(int i=0;i<n;i++) if(a[i][0]==ch) { fun(a[i][1]);//递归,输出左节点 fun(a[i][2]);//递归,输出右节点 } }
代码实现
#include<bits/stdc++.h>
using namespace std;
int n;
char a[50][3];
void fun(char ch)
{
if(ch!='*')
{
cout<<ch;//输出根节点
for(int i=0;i<n;i++)
if(a[i][0]==ch)
{
fun(a[i][1]);//递归,输出左节点
fun(a[i][2]);//递归,输出右节点
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<3;j++)
{
cin>>a[i][j];
}
fun(a[0][0]);
return 0;
}
P1030 [NOIP2001 普及组] 求先序排列
题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度\le 8≤8)。
输入格式
22行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
11行,表示一棵二叉树的先序。
输入输出样例
输入 #1复制
BADC BDCA
输出 #1复制
ABCD
说明/提示
【题目来源】
NOIP 2001 普及组第三题
思路
这和第一个题思路不是一毛一样的!!!稍微改一下就好了
1、分别用字符串a,b存储后序和中序
2、设后序的起点与终点是a1,a2-1,中序的起点与终点是b1,b2-1
3、要知道后序遍历(左右根)的最后一个结点是根节点
4、所以在中序遍历(左根右)中找到a2-1,记录其位置为k;k的左边就是左子树。右边就是右子树
5、用n,m存储左右子树结点个数
6、当n>0时即左子树结点个数不为零时,递归;
7、当m>0时即右子树结点个数不为零时,递归;
cout<<a[a2-1];//输出根节点(前序遍历,根左右) int k;//用于保存中序遍历中根节点的位置 for(int i=b1;i<b2;i++) { if(b[i]==a[a2-1]) { k=i; break; } } int n=k-b1;//左子树的结点个数 int m=b2-(k+1);//右子树的节点个数 if(n>0) fun(a1,a1+n,b1,b1+n); if(m>0) fun(a2-1-m,a2-1,k+1,k+1+m);
代码实现
#include<bits/stdc++.h>
using namespace std;
char a[100],b[100];
void fun(int a1,int a2,int b1,int b2)
{
cout<<a[a2-1];//输出根节点(前序遍历,根左右)
int k;//用于保存中序遍历中根节点的位置
for(int i=b1;i<b2;i++)
{
if(b[i]==a[a2-1])
{
k=i;
break;
}
}
int n=k-b1;//左子树的结点个数
int m=b2-(k+1);//右子树的节点个数
if(n>0)
fun(a1,a1+n,b1,b1+n);
if(m>0)
fun(a2-1-m,a2-1,k+1,k+1+m);
return;
}
int main()
{
int len;
cin>>b>>a;
len=strlen(b);
//cout<<len;
fun(0,len,0,len);
return 0;
}
P1177 【模板】快速排序
题目描述
利用快速排序算法将读入的 NN 个数从小到大排序后输出。
快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL
,虽然你可以使用 sort
一遍过,但是你并没有掌握快速排序算法的精髓。)
输入格式
第 11 行为一个正整数 NN,第 22 行包含 NN 个空格隔开的正整数 a_iai,为你需要进行排序的数,数据保证了 A_iAi 不超过 10^9109。
输出格式
将给定的 NN 个数从小到大输出,数之间空格隔开,行末换行且无空格。
输入输出样例
输入 #1复制
5 4 2 4 5 1
输出 #1复制
1 2 4 4 5
说明/提示
对于 20\%20% 的数据,有 N\leq 10^3N≤103;
对于 100\%100% 的数据,有 N\leq 10^5N≤105。
思路
本来想直接ac的,谁知道传统的快排后三个点都是tle
经过n小时对普通快排的优化(淦!还是不对!!),于是只能换个思路,真伤脑筋呀(这个的思路是学习一个大佬的)。
1、利用二分思想,
2、mid=a[(l+r)/2];
3、从左边找比中间数大的数,右边找比中间数小的数,进行交换;循环操作,直到i>j
4、进行递归
if(l<j) qsort(l,j); if(i<r) qsort(i,r);
代码实现
#include<bits/stdc++.h>
using namespace std;
int n,a[1000001];
void qsort(int l,int r)
{
int mid=a[(l+r)/2];
int i=l,j=r;
do{
while(a[i]<mid) i++;//左边比中间数大的数
while(a[j]>mid) j--;//右边比中间数小的数
if(i<=j)
{
swap(a[i],a[j]);//交换
i++;
j--;
}
}while(i<=j);
if(l<j)
qsort(l,j);
if(i<r)
qsort(i,r);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
qsort(1,n);
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}