团体天梯练习 L2-006 树的遍历

Posted MAKISE004

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了团体天梯练习 L2-006 树的遍历相关的知识,希望对你有一定的参考价值。

L2-006 树的遍历

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

输入格式:

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

输出格式:

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

输入样例:

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

输出样例:

4 1 6 3 5 7 2


解题思路

比较考验数据结构基础的题,涉及到了根据二叉树的中序遍历和后序遍历构建二叉树,还有层序遍历。还是比较简单的,leetcode上有类似的题,我自己之前写过相关的随笔。根据前中后序遍历中的两种构造二叉树

/*   一切都是命运石之门的选择  El Psy Kongroo  */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, pii> psi;
typedef __int128 int128;
#define PI acos(-1.0)
#define x first
#define y second
//int dx[4] = 1, -1, 0, 0;
//int dy[4] = 0, 0, 1, -1;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;


vector<int> post;   //后序遍历序列
vector<int> res;
int n;
const int N = 33;
map<int, int> inpos;    //中序遍历对应节点值的下标
typedef struct Node
    int val;
    struct Node *left, *right;
Node;

//根据中序遍历和后序遍历构建二叉树
Node* build(int in_left, int in_right, int po_left, int po_right)
    if(in_left > in_right || po_left > po_right) return NULL;
    int val = post[po_right];   //后序遍历最右边的为根节点
    int in_mid = inpos[val];    //在中序遍历中找到该节点下标
    int num = in_mid - in_left; //左子树节点个数
    
    Node* root = new Node;
    root->val = val;
    root->left = build(in_left, in_mid - 1, po_left, po_left + num - 1);  
    root->right = build(in_mid + 1, in_right, po_left + num, po_right - 1);
    return root;


//层序遍历
void bfs(Node* root)
    queue<Node*> q;
    q.push(root);
    while(!q.empty())
        int n = q.size();
        for(int i = 0; i < n; i ++ )
            Node* t = q.front();
            res.push_back(t->val);
            q.pop();
            
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        
    


void show()
    for(int i = 0; i < (int)res.size() - 1; i ++ ) cout << res[i] << \' \';
    cout << res.back() << endl;


int main()
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    cin >> n;
    for(int i = 0; i < n; i ++ )
        int x; cin >> x;
        post.push_back(x);
    
    for(int i = 0; i < n; i ++ )
        int x; cin >> x;
        inpos[x] = i;    //只需要记录中序遍历每个值对应下标就可以了
    
    
    Node *root = build(0, n - 1, 0, n - 1);
    
    bfs(root);

    show();

    return 0;

PTA2022年蓝桥杯及天梯赛赛前训练(C++练习)

【PTA】2022年蓝桥杯及天梯赛赛前训练(C++练习)

前言

团体程序设计天梯赛-练习集 PTA上面的基础题,作为C++的小练习~~

L1-1 嫑废话上代码

Linux 之父 Linus Torvalds 的名言是:“Talk is cheap. Show me the code.”(嫑废话,上代码)。本题就请你直接在屏幕上输出这句话。

输入格式:
本题没有输入。

输出格式:
在一行中输出 Talk is cheap. Show me the code.
#include<iostream>
using namespace std;

int main()

	cout  << "Talk is cheap. Show me the code." << "";

L1-2 猫是液体

测量一个人的体积是很难的,但猫就不一样了。因为猫是液体,所以可以很容易地通过测量一个长方体容器的容积来得到容器里猫的体积。本题就请你完成这个计算。

输入格式:
输入在第一行中给出 3 个不超过 100 的正整数,分别对应容器的长、宽、高。

输出格式:
在一行中输出猫的体积。

输入样例:
23 15 20
输出样例:
6900
#include<iostream>
using namespace std;

int main()

	int a, b, c;
	cin >> a >> b >> c;
	cout  << a*b*c << "";

L1-3 洛希极限

科幻电影《流浪地球》中一个重要的情节是地球距离木星太近时,大气开始被木星吸走,而随着不断接近地木“刚体洛希极限”,地球面临被彻底撕碎的危险。但实际上,这个计算是错误的。

洛希极限(Roche limit)是一个天体自身的引力与第二个天体造成的潮汐力相等时的距离。当两个天体的距离少于洛希极限,天体就会倾向碎散,继而成为第二个天体的环。它以首位计算这个极限的人爱德华·洛希命名。(摘自百度百科)

大天体密度与小天体的密度的比值开 3 次方后,再乘以大天体的半径以及一个倍数(流体对应的倍数是 2.455,刚体对应的倍数是 1.26),就是洛希极限的值。例如木星与地球的密度比值开 3 次方是 0.622,如果假设地球是流体,那么洛希极限就是 0.622×2.455=1.52701 倍木星半径;但地球是刚体,对应的洛希极限是 0.622×1.26=0.78372 倍木星半径,这个距离比木星半径小,即只有当地球位于木星内部的时候才会被撕碎,换言之,就是地球不可能被撕碎。

本题就请你判断一个小天体会不会被一个大天体撕碎。

输入格式:
输入在一行中给出 3 个数字,依次为:大天体密度与小天体的密度的比值开 3 次方后计算出的值(≤1)、小天体的属性(0 表示流体、1 表示刚体)、两个天体的距离与大天体半径的比值(>1 但不超过 10)。

输出格式:
在一行中首先输出小天体的洛希极限与大天体半径的比值(输出小数点后2位);随后空一格;最后输出 ^_^ 如果小天体不会被撕碎,否则输出 T_T。

输入样例 10.622 0 1.4
输出样例 11.53 T_T
输入样例 20.622 1 1.4
输出样例 20.78 ^_^
import java.util.Scanner;

public class Main 
	public static void main(String[] args) 
		Scanner sc = new Scanner(System.in);
		double a = sc.nextDouble();
		int b = sc.nextInt();
		double c = sc.nextDouble();
		double d = 0;
		if (b == 0) 
			d = a*2.455;
			System.out.printf("%.2f ", d);
		 else 
			d = a*1.26;
			System.out.printf("%.2f ", d);
		
		if (d < c) 
			System.out.println("^_^");
		 else 
			System.out.println("T_T");
		
	

L1-4 调和平均

N 个正数的算数平均是这些数的和除以 N,它们的调和平均是它们倒数的算数平均的倒数。本题就请你计算给定的一系列正数的调和平均值。

输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 N (1000);第 2 行给出 N 个正数,都在区间 [0.1,100] 内。

输出格式:
在一行中输出给定数列的调和平均值,输出小数点后2位。

输入样例:
8
10 15 12.7 0.3 4 13 1 15.6
输出样例:
1.61
#include<bits/stdc++.h>
using namespace std;

int main()

	int a, d;
	double sum, b;
	cin >> a;
	d = a;
	while (d--)
	
		cin >> b;
		sum += 1/b;
	
	
	printf("%.2f", a/sum);
	
	return 0;

L1-5 胎压监测

小轿车中有一个系统随时监测四个车轮的胎压,如果四轮胎压不是很平衡,则可能对行车造成严重的影响。

让我们把四个车轮 —— 左前轮、右前轮、右后轮、左后轮 —— 顺次编号为 1234。本题就请你编写一个监测程序,随时监测四轮的胎压,并给出正确的报警信息。报警规则如下:

如果所有轮胎的压力值与它们中的最大值误差在一个给定阈值内,并且都不低于系统设定的最低报警胎压,则说明情况正常,不报警;
如果存在一个轮胎的压力值与它们中的最大值误差超过了阈值,或者低于系统设定的最低报警胎压,则不仅要报警,而且要给出可能漏气的轮胎的准确位置;
如果存在两个或两个以上轮胎的压力值与它们中的最大值误差超过了阈值,或者低于系统设定的最低报警胎压,则报警要求检查所有轮胎。
输入格式:
输入在一行中给出 6[0, 400] 范围内的整数,依次为 1~4 号轮胎的胎压、最低报警胎压、以及胎压差的阈值。

输出格式:
根据输入的胎压值给出对应信息:

如果不用报警,输出 Normal;
如果有一个轮胎需要报警,输出 Warning: please check #X!,其中 X 是出问题的轮胎的编号;
如果需要检查所有轮胎,输出 Warning: please check all the tires!。

输入样例 1242 251 231 248 230 20
输出样例 1:
Normal
输入样例 2242 251 232 248 230 10
输出样例 2:
Warning: please check #3!
输入样例 3240 251 232 248 240 10
输出样例 3:
Warning: please check all the tires!
#include<bits/stdc++.h>
using namespace std;

int a[6];
int main()

	int a_index = 0, aa = 0, c, max = 0;
	for (int i = 0; i < 4; i++)
	
		cin >> a[i];
		max = a[i] > max ? a[i] : max;
	
	cin >> a[4] >> a[5];
	
	for (int i = 0; i < 4; i++)
	
		if (max-a[i] > a[5] || a[i] < a[4]) 
			aa++;
			a_index = i;
		
	
	if (aa == 0)
		cout << "Normal" << endl;
	else if (aa == 1)
		printf("Warning: please check #%d!", a_index+1);
	else
		cout << "Warning: please check all the tires!" << endl;
	
	return 0;

L1-6 吃火锅

以上图片来自微信朋友圈:这种天气你有什么破事打电话给我基本没用。但是如果你说“吃火锅”,那就厉害了,我们的故事就开始了。

本题要求你实现一个程序,自动检查你朋友给你发来的信息里有没有 chi1 huo3 guo1。

输入格式:
输入每行给出一句不超过 80 个字符的、以回车结尾的朋友信息,信息为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。当读到某一行只有一个英文句点 . 时,输入结束,此行不算在朋友信息里。

输出格式:
首先在一行中输出朋友信息的总条数。然后对朋友的每一行信息,检查其中是否包含 chi1 huo3 guo1,并且统计这样厉害的信息有多少条。在第二行中首先输出第一次出现 chi1 huo3 guo1 的信息是第几条(从 1 开始计数),然后输出这类信息的总条数,其间以一个空格分隔。题目保证输出的所有数字不超过 100。

如果朋友从头到尾都没提 chi1 huo3 guo1 这个关键词,则在第二行输出一个表情 -_-#。

输入样例 1:
Hello!
are you there?
wantta chi1 huo3 guo1?
that's so li hai le
our story begins from chi1 huo3 guo1 le
.
输出样例 15
3 2
输入样例 2:
Hello!
are you there?
wantta qi huo3 guo1 chi1huo3guo1?
that's so li hai le
our story begins from ci1 huo4 guo2 le
.
输出样例 25
-_-#
#include<bits/stdc++.h>
using namespace std;

int main()

	int i = 0, j = 0, index = 0;
	string a;
	do 
		i++;
		getline(cin, a);
		if (a.find("chi1 huo3 guo1") <= 80 && a.find("chi1 huo3 guo1") >= 0) 
			if (j == 0)
				index = i;
			j++;
		
		
	 while (a != ".");
	cout << i-1 << endl;
	if (j == 0)
		cout << "-_-#" << endl;
	else 
		cout << index << " " << j << endl;
	return 0;

L1-7 前世档案


网络世界中时常会遇到这类滑稽的算命小程序,实现原理很简单,随便设计几个问题,根据玩家对每个问题的回答选择一条判断树中的路径(如下图所示),结论就是路径终点对应的那个结点。

现在我们把结论从左到右顺序编号,编号从 1 开始。这里假设回答都是简单的“是”或“否”,又假设回答“是”对应向左的路径,回答“否”对应向右的路径。给定玩家的一系列回答,请你返回其得到的结论的编号。

输入格式:
输入第一行给出两个正整数:N(≤30)为玩家做一次测试要回答的问题数量;M(≤100)为玩家人数。

随后 M 行,每行顺次给出玩家的 N 个回答。这里用 y 代表“是”,用 n 代表“否”。

输出格式:
对每个玩家,在一行中输出其对应的结论的编号。

输入样例:
3 4
yny
nyy
nyn
yyn
输出样例:
3
5
6
2
#include<bits/stdc++.h>
using namespace std;

int main()

	int i = 0, j = 0;
	cin >> i >> j;
	string s;
	int a, sum;
	while (j--)
	
		int sum = 0;
		cin >> s;
		a = pow(2, i-1);
		for (int k = 0; k < sizeof(s); k++)
		
			if (s[k] == 'n') 
				sum += a;
			
			a /= 2;
		
		cout << sum+1 << endl;
	
	
	return 0;

Java:

import java.util.Scanner;

public class L1_7 
    public static void main(String[] args) 
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        sc.nextLine();
        while (m-- > 0) 
            String fate = sc.nextLine();
            /*int ans = 0;
            for (int i = 0; i < fate.length(); i++) 
                ans *= 2;
                if (fate.charAt(i) == 'y')
                    ans += 0;
                else if (fate.charAt(i) == 'n')
                    ans += 1;
            
            System.out.println(ans+1);*/

            // 解法二
            int root = 1;
            int t = (int) Math.pow(2, n);
            for (int i = 0; i < fate.length(); i++) 
                if (fate.charAt(i) == 'y')
                     root *= 2;
                else if (fate.charAt(i) == 'n')
                    root = root * 2 +1;
            
            System.out.println(root-t+1);
        
    

L1-8 刮刮彩票

“刮刮彩票”是一款网络游戏里面的一个小游戏。如图所示:

每次游戏玩家会拿到一张彩票,上面会有 9 个数字,分别为数字 1 到数字 9,数字各不重复,并以 3×3 的“九宫格”形式排布在彩票上。

在游戏开始时能看见一个位置上的数字,其他位置上的数字均不可见。你可以选择三个位置的数字刮开,这样玩家就能看见四个位置上的数字了。最后玩家再从 3 横、3 竖、2 斜共 8 个方向中挑选一个方向,方向上三个数字的和可根据下列表格进行兑奖,获得对应数额的金币。

数字合计获得金币数字合计获得金币
610,0001672
73617180
872018119
93601936
108020306
11252211,080
1210822144
1372231,800
1454243,600
15180

现在请你写出一个模拟程序,模拟玩家的游戏过程。

输入格式:
输入第一部分给出一张合法的彩票,即用 33 列给出 09 的数字。0 表示的是这个位置上的数字初始时就能看见了,而不是彩票上的数字为 0。

第二部给出玩家刮开的三个位置,分为三行,每行按格式 x y 给出玩家刮开的位置的行号和列号(题目中定义左上角的位置为第 1 行、第 1 列。)。数据保证玩家不会重复刮开已刮开的数字。

最后一部分给出玩家选择的方向,即一个整数: 13 表示选择横向的第一行、第二行、第三行,46 表示纵向的第一列、第二列、第三列,78分别表示左上到右下的主对角线和右上到左下的副对角线。

输出格式:
对于每一个刮开的操作,在一行中输出玩家能看到的数字。最后对于选择的方向,在一行中输出玩家获得的金币数量。

输入样例:
1 2 3
4 5 6
7 8 0
1 1
2 2
2 3
7
输出样例:
1
5
6
180
#include<bits/stdc++.h>
using namespace std;

int a[4][4];
int b[] = 10000, 36, 720, 360, 80, 252, 108, 72, 54, 180, 72, 180, 119, 36, 306, 1080, 144, 1800, 3600;
int main()

	int aa = 0, sum = 0, c, d;
	for (int i = 1; i < 4; i++) 
		for (int j = 1; j < 4; j++) 
			cin >> a[i][j];
			aa += a[i][j];
			if (a[i][j] == 0) 
			
				c = i;
				d = j;
			
		
	
	a[c][d] = 45 - aa;
	sum = 0;
	
	int x, y;
	for (int i = 1; i < 4; i++) 
		cin >> x >> y;
		cout << a[x][y] << endl;
	
	cin >> x;
	if (x < 4)
	
		for (int i = 1; i < 4; i++) 
		
			sum += a[x][i];
		
	 
	else if (x < 7) 
	
		for (int i = 1; i < 4; i++) 
		
			sum += a[i][x-3];
		
	 
	else if (x == 7)
	
		for (int i = 1; i < 4; i++) 
		
			sum += a[i][i];
		
	
	else
	
		for (int i = 1; i < 4; i++) 
		
			sum += a[i][4-i];
		
	
	cout << b[sum-6] << endl;
	return 0;

L2-1 简单计算器


本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。如上图所示,计算器由两个堆栈组成,一个堆栈S存放数字,另一个堆栈Sg存放运算符。计算器的最下方有一个等号键,每次按下这个键,计算器就执行以下操作:

  1. 从S1中弹出两个数字,顺序为n1和n2;
  2. 从S中弹出一个运算符op;
  3. 执行计算n2 op n1;
  4. 将得到的结果压回S1。

直到两个堆栈都为空时,计算结束,最后的结果将显示在屏幕上。

输入样例 15
40 5 8 3 2
/ * - +
输出样例 12
输入样例 25
2 5 8 4 4
* / - +
输出样例 2:
ERROR: 5/0
#include<bits/stdc++.h>
using namespace std;

int a[10010];
char c[10010];
int main()

	int n, top1 = -1, top2 = -1;
	cin >> n;
	for (int i = 0; i < n; i++) 
		cin >> a[++top1];
	
	for (int i = 0; i < n-1; i++) 
		cin >> c[++top2];
	
	int op1, op2PAT  团体程序设计天梯赛-练习集 L2-006. 树的遍历

团体程序设计天梯赛 L2-006. 树的遍历 L2-011. 玩转二叉树

天梯赛L2-006. 树的遍历

天梯赛 L2-006 树的遍历(序列建树)

L2-006.树的遍历

L2-006. 树的遍历