PAT甲级相关树的题目

PAT甲级相关树的题目:

相关题目

1004 Counting Leaves

分数 30
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 0<N<100, the number of nodes in a tree, and M (<N), the number of non-leaf nodes. Then M lines follow, each in the format:
ID K ID[1] ID[2] … ID[K]
where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 01.
The input ends with N being 0. That case must NOT be processed.
Output Specification:
For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.
The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.

Sample Input:
2 1
01 1 02
Sample Output:
0 1

题解:层序遍历

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 105;

int n, m;
bool st[N];
vector<int>vec[N];

void bfs(){
	vector<int>res;
	queue<int>que;
	que.push(1);
	while(!que.empty()){
		int len = que.size();
		int cou = 0;
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			for(auto it : vec[Top]) que.push(it);
			if(!st[Top]) cou ++;
		}
		res.push_back(cou);
	}
	for(int i = 0, len = res.size(); i < len; i ++ ){
		printf("%d%s", res[i], i == len - 1 ? "" : " ");
	}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; i ++ ){
		int fa, son, k;
		cin >> fa >> k;
		while(k -- ){
			cin >> son;
			vec[fa].push_back(son);
		}
		st[fa] = true;
	}
	bfs();
	return 0;
}

1020 Tree Traversals

分数 25
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

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

题解:中序后序构造二叉树,层序输出

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 35;

int n;
int postorder[N], inorder[N];

struct node{
	int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){//post,in
	if(l1 >= r1) return -1;
	int val = r1 - 1;
	if(r1 - l1 == 1){
		stu[val] = {-1, -1};
		return val;
	}
	int pos = l2;
	while(pos < r2 && inorder[pos] != postorder[val]) pos ++;
	stu[val].l = dfs(l1, l1 + pos - l2, l2, pos);
	stu[val].r = dfs(l1 + pos - l2, r1 - 1, pos + 1, r2);
	return val;
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	vector<int>res;
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int cur = que.front();que.pop();
			if(stu[cur].l != -1) que.push(stu[cur].l);
			if(stu[cur].r != -1) que.push(stu[cur].r);
			res.push_back(postorder[cur]);
		}
	}
	for(int i = 0; i < n; i ++ ) printf("%d%s", res[i], i == n - 1 ? "" : " ");
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> postorder[i];
	for(int i = 0; i < n; i ++ ) cin >> inorder[i];
	int root = dfs(0, n, 0, n);
	bfs(root);
	return 0;
}

1043 Is It a Binary Search Tree

分数 25
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.
Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤1000). Then N integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, first print in a line YES if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or NO if not. Then if the answer is YES, print in the next line the postorder traversal sequence of that tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:
7
8 6 5 7 10 8 11
Sample Output 1:
YES
5 7 6 8 11 10 8
Sample Input 2:
7
8 10 11 8 6 7 5
Sample Output 2:
YES
11 8 10 7 5 6 8
Sample Input 3:
7
8 6 8 5 10 9 11
Sample Output 3:
NO

题解:
1.分别由前序构建BST和MBST
2.中序遍历BST(升序)和MBST(降序),括号内的为两棵树中序遍历的特性
3.满足条件就后序遍历并输出

#include<unordered_map>
#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 1E3 + 5;

int n;
int pre[N];

struct node{
	int l, r;
}BST[N], MBST[N];

int dfs_bst(int l, int r){
	if(l >= r) return -1;
	if(r - l == 1){
		BST[l] = {-1, -1};
		return l;
	}
	int i = l + 1, val = pre[l];
	while(i < r && pre[i] < val) i ++;
	BST[l].l = dfs_bst(l + 1, i);
	BST[l].r = dfs_bst(i, r);
	return l;
}

int dfs_mbst(int l, int r){
	if(l >= r) return -1;
	if(r - l == 1){
		MBST[l] = {-1, -1};
		return l;
	}
	int i = l + 1, val = pre[l];
	while(i < r && pre[i] >= val) i ++;
	MBST[l].l = dfs_mbst(l + 1, i);
	MBST[l].r = dfs_mbst(i, r);
	return l;
}

void inorder_traversal(int root, bool flag, vector<int>&res){
	if(root == -1) return;
	if(flag) inorder_traversal(BST[root].l, flag, res);
	else inorder_traversal(MBST[root].l, flag, res);
	res.push_back(pre[root]);
	if(flag) inorder_traversal(BST[root].r, flag, res);
	else inorder_traversal(MBST[root].r, flag, res);
}

void post_traversal(int root, bool flag, vector<int>&res){
	if(root == -1) return;
	if(flag) post_traversal(BST[root].l, flag, res);
	else post_traversal(MBST[root].l, flag, res);
	if(flag) post_traversal(BST[root].r, flag, res);
	else post_traversal(MBST[root].r, flag, res);
	res.push_back(pre[root]);
}

bool check(bool flag){
	vector<int>res;
	inorder_traversal(0, flag, res);
	if(flag){
		for(int i = 1, len = res.size(); i < len; i ++ ){
			if(res[i] < res[i - 1]) return false;
		}
		res.clear();
		post_traversal(0, flag, res);
		cout << "YES\n";
		for(int i = 0, len = res.size(); i < len; i ++ ){
			printf("%d%s", res[i], i == len - 1 ? "" : " ");	
		}
		return true;
	}
	else{
		for(int i = 1, len = res.size(); i < len; i ++ ){
			if(res[i] > res[i - 1]) return false;
		}
		res.clear();
		post_traversal(0, flag, res);
		cout << "YES\n";
		for(int i = 0, len = res.size(); i < len; i ++ ){
			printf("%d%s", res[i], i == len - 1 ? "" : " ");	
		}
		return true;
	}
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> pre[i];
	dfs_bst(0, n);
	bool flag = check(1);
	if(flag) return 0;
	dfs_mbst(0, n);
	flag = check(0);
	if(!flag) cout << "NO"; 
	return 0;
}

1053 Path of Equal Weight

分数 30
Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L.
Now given any weighted tree, you are supposed to find all the paths with their weights equal to a given number. For example, let’s consider the tree showed in the following figure: for each node, the upper number is the node ID which is a two-digit number, and the lower number is the weight of that node. Suppose that the given number is 24, then there exists 4 different paths which have the same given weight: {10 5 2 7}, {10 4 10}, {10 3 3 6 2} and {10 3 3 6 2}, which correspond to the red edges in the figure.

在这里插入图片描述
Input Specification:
Each input file contains one test case. Each case starts with a line containing 0<N≤100, the number of nodes in a tree, M (<N), the number of non-leaf nodes, and 0<S< 2 30 2^{30} 230, the given weight number. The next line contains N positive numbers where Wi (<1000) corresponds to the tree node Ti.Then M lines follow, each in the format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 00.

Output Specification:
For each test case, print all the paths with weight S in non-increasing order. Each path occupies a line with printed weights from the root to the leaf in order. All the numbers must be separated by a space with no extra space at the end of the line.
Note: sequence { A 1 , A 2 , ⋯ , A n A_1,A_2,⋯,A_n A1,A2,,An} is said to be greater than sequence { B 1 , B 2 , ⋯ , B m B_1,B_2,⋯,B_m B1,B2,,Bm} if there exists 1≤k<min{ n , m {n,m} n,m} such that A i = B i A_i =B_i Ai=Bi for i = 1 , ⋯ , k , i=1,⋯,k, i=1,,k, and A k + 1 > B k + 1 A_{k+1}>B_{k+1} Ak+1>Bk+1.

Sample Input:
20 9 24
10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2
00 4 01 02 03 04
02 1 05
04 2 06 07
03 3 11 12 13
06 1 09
07 2 08 10
16 1 15
13 3 14 16 17
17 2 18 19
Sample Output:
10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2

题解:
1.dfs一遍求出所有路径并存储
2.用sort排序,默认升序,greater为降序

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int N = 105;

int n, m, k;
int w[N];

bool st[N];
vector<int>vec[N];
vector<vector<int>>res;
vector<int>tem;

void dfs(int root, int sum){
	if(!st[root] && sum == k){
		res.push_back(tem);
		return;
	}
	for(auto it : vec[root]){
		tem.push_back(w[it]);
		dfs(it, sum + w[it]);
		tem.pop_back();
	}
}

int main(){
	cin >> n >> m >> k;
	for(int i = 0; i < n; i ++ ) cin >> w[i];
	for(int i = 0; i < m; i ++ ){
		int fa, k, son;
		cin >> fa >> k;
		st[fa] = true;
		for(int j = 1; j <= k; j ++ ){
			cin >> son;
			vec[fa].push_back(son);	
		}
	}
	tem.push_back(w[0]);
	dfs(0, w[0]);
	sort(res.begin(), res.end(), greater<vector<int>>());
	for(int i = 0, len = res.size(); i < len; i ++ ){
		for(int j = 0, len1 = res[i].size(); j < len1; j ++ ){
			printf("%d%s", res[i][j], j == len1 - 1 ? "" : " ");
		}
		printf("\n");
	}
	return 0;
}

1064 Complete Binary Search Tree

分数 30
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
  • Both the left and right subtrees must also be binary search trees.

A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input:
10
1 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4

题解:
1.对原数组升序排序,即为该完全二叉搜索树的中序
2.根据中序,递归的划分左儿子的最大个数,然而分段递归
3.层序输出

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int N = 1E3 + 5;

int n;
int in[N];
vector<int>res;

struct node{
	int l, r;
}stu[N];

int dfs(int l, int r){
	if(l >= r) return -1;
	if(r - l == 1){
		stu[l] = {-1, -1};
		return l;
	}
	int sum = 0, cou = r - l, i = 0;
	while(true){
		int val = 1 << i;
		if(cou <= val) break;
		sum += val / 2;
		cou -= val;
		i ++;
	}
	sum += min((1 << i) / 2, cou);
	int root = l + sum;
	stu[root].l = dfs(l, root);
	stu[root].r = dfs(root + 1, r);
	return root;
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			res.push_back(in[Top]);
		}
	}
	for(int i = 0, len = res.size(); i < len; i ++ ){
		printf("%d%s", res[i], i == len - 1 ? "" : " ");
	}
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> in[i];
	sort(in, in + n);
	int root = dfs(0, n);
	bfs(root);
	return 0;
}

1079 Total Sales of Supply Chain

分数 25
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the total sales from all the retailers.

Input Specification:
Each input file contains one test case. For each case, the first line contains three positive numbers: N (≤ 1 0 5 10^5 105), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N−1, and the root supplier’s ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:
K i I D [ 1 ] , I D [ 2 ] . . . I D [ K i ] K_i ID[1],ID[2]...ID[K_i] KiID[1],ID[2]...ID[Ki]
where in the i-th line, K i K_i Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. K j K_j Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after K j K_j Kj. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place. It is guaranteed that the number will not exceed 1 0 10 10^{10} 1010.

Sample Input:
10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3
Sample Output:
42.4

题解:
1.记录每一个retailer的sales可以先放大1000倍,最后答案再除以1000,可以一定程度上保证精度

#include<iostream>
#include<vector>
#include<queue>
#include<cmath>

using namespace std;

const int N = 1E5 + 5;

int n;
double price, r;
int st[N];
double res;
vector<int>vec[N];

void dfs(int root, int depth){
	if(st[root]){
		res += 1.0 * st[root] * 1000 * price *  pow((0.01 * r + 1), depth);
		return;
	}
	for(auto it : vec[root]) dfs(it, depth + 1);
}

int main(){
	cin >> n >> price >> r;
	for(int i = 0; i < n; i ++ ){
		int x, k;
		cin >> k;
		if(k){
			for(int j = 1; j <= k; j ++ ){
				cin >> x;
				vec[i].push_back(x);
			}
		}
		else cin >> st[i];
	}
	dfs(0, 0);
	printf("%.1lf", res / 1000);
	return 0;
}

1090 Highest Price in Supply Chain

分数 25
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the highest price we can expect from some retailers.

Input Specification:
Each input file contains one test case. For each case, The first line contains three positive numbers: N (≤ 1 0 5 10^5 105), the total number of the members in the supply chain (and hence they are numbered from 0 to N−1); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then the next line contains N numbers, each number S i S_i Si is the index of the supplier for the i-th member. S r o o t S_{root} Sroot for the root supplier is defined to be −1. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the highest price we can expect from some retailers, accurate up to 2 decimal places, and the number of retailers that sell at the highest price. There must be one space between the two numbers. It is guaranteed that the price will not exceed 1 0 10 10^{10} 1010

Sample Input:
9 1.80 1.00
1 5 4 4 -1 4 5 3 6
Sample Output:
1.85 2

题解:
1.创建并遍历树,求出深度最大,且求出深度最大的个数

#include<iostream>
#include<vector>
#include<queue>
#include<cmath>

using namespace std;

const int N = 1E5 + 5;

int n;
double price, r;
bool st[N];
vector<int>vec[N];
int res, dep;

void dfs(int root, int depth){
	if(!st[root]){
		if(depth > dep) dep = depth, res = 1;
		else if(depth == dep) res ++;
		return;
	}
	for(auto it : vec[root]) dfs(it, depth + 1);
}

int main(){
	cin >> n >> price >> r;
	int root;
	for(int i = 0; i < n; i ++ ){
		int x;
		cin >> x;
		st[x] = true;
		if(x != -1) vec[x].push_back(i);
		else root = i;
	}
	dfs(root, 0);
	double val = price * pow(0.01 * r + 1, dep);
	printf("%.2lf %d", val, res);
	return 0;
}

1106 Lowest Price in Supply Chain

分数 25
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the lowest price a customer can expect from some retailers.

Input Specification:
Each input file contains one test case. For each case, The first line contains three positive numbers: N (≤ 1 0 5 10^5 105), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N−1, and the root supplier’s ID is 0); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:
K i I D [ 1 ] I D [ 2 ] . . . I D [ K i ] K_i ID[1] ID[2] ... ID[K_i] KiID[1]ID[2]...ID[Ki]

where in the i-th line, K i K_i Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. K j K_j Kj being 0 means that the j-th member is a retailer. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the lowest price we can expect from some retailers, accurate up to 4 decimal places, and the number of retailers that sell at the lowest price. There must be one space between the two numbers. It is guaranteed that the all the prices will not exceed 1 0 10 10^{10} 1010 .

Sample Input:
10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0
2 6 1
1 8
0
0
0
Sample Output:
1.8362 2

题解:
1.1.创建并遍历树,求出深度最小,且求出深度最小的个数

#include<iostream>
#include<vector>
#include<queue>
#include<cmath>

using namespace std;

const int N = 1E5 + 5;

int n;
double price, r;
bool st[N];
vector<int>vec[N];
int res, dep = 0x3f3f3f3f;

void dfs(int root, int depth){
	if(st[root]){
		if(depth < dep) dep = depth, res = 1;
		else if(depth == dep) res ++;
		return;
	}
	for(auto it : vec[root]) dfs(it, depth + 1);
}

int main(){
	cin >> n >> price >> r;
	for(int i = 0; i < n; i ++ ){
		int k, son;
		cin >> k;
		if(k){
			for(int j = 1; j <= k; j ++ ){
				cin >> son;
				vec[i].push_back(son);
			}
		}
		else st[i] = true;
	}
	dfs(0, 0);
	double val = price * pow(0.01 * r + 1, dep);
	printf("%.4lf %d", val, res);
	return 0;
}

1086 Tree Traversals Again

分数 25
An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

在这里插入图片描述

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
3 4 2 6 5 1

题解
1.push操作的是前序,pop操作是中序
2.根据前序和中序构建二叉树,并输出后序

#include<iostream>
#include<vector>
#include<queue>
#include<stack>

using namespace std;

const int N = 35;

int n;
int cnt1, cnt2;
int pre[N], in[N];
stack<int>stk;
vector<int>res;

struct node{
	int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
	if(l1 >= r1) return -1;
	if(r1 - l1 == 1){
		stu[l1] = {-1, -1};
		return l1;
	}
	int i = l2, val = pre[l1];
	while(i < r2 && in[i] != val) i ++;
	stu[l1].l = dfs(l1 + 1, l1 + 1 + i - l2, l2, i);
	stu[l1].r = dfs(l1 + 1 + i - l2, r1, i + 1, r2);
	return l1;
}

void post_traversal(int root){
	if(root == -1) return;
	post_traversal(stu[root].l);
	post_traversal(stu[root].r);
	res.push_back(pre[root]);
}

int main(){
	cin >> n;
	for(int i = 1; i <= n + n; i ++ ){
		string s;
		int x;
		cin >> s;
		if(s == "Push"){
			cin >> x;
			stk.push(x);
			pre[cnt1 ++] = x;
		}
		else if(s == "Pop"){
			x = stk.top();stk.pop();
			in[cnt2 ++] = x;
		}
	}
	int root = dfs(0, n, 0, n);
	post_traversal(root);
	for(int i = 0; i < n; i ++ ) printf("%d%s", res[i], i == n - 1 ? "" : " ");
	return 0;
}

1094 The Largest Generation

分数 25
A family hierarchy is usually presented by a pedigree tree where all the nodes on the same level belong to the same generation. Your task is to find the generation with the largest population.

Input Specification:
Each input file contains one test case. Each case starts with two positive integers N (<100) which is the total number of family members in the tree (and hence assume that all the members are numbered from 01 to N), and M (<N) which is the number of family members who have children. Then M lines follow, each contains the information of a family member in the following format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a family member, K (>0) is the number of his/her children, followed by a sequence of two-digit ID’s of his/her children. For the sake of simplicity, let us fix the root ID to be 01. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the largest population number and the level of the corresponding generation. It is assumed that such a generation is unique, and the root level is defined to be 1.

Sample Input:
23 13
21 1 23
01 4 03 02 04 05
03 3 06 07 08
06 2 12 13
13 1 21
08 2 15 16
02 2 09 10
11 2 19 20
17 1 22
05 1 11
07 1 14
09 1 17
10 1 18
Sample Output:
9 4

题解
1.层序遍历求出层数中个数的最多的那一层和它的个数

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 105;

int n, m;
bool st[N];
int res, dep;
vector<int>vec[N];

void bfs(int root){
	queue<int>que;
	que.push(root);
	int depth = 1;
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			for(auto it : vec[Top]) que.push(it);
		}
		if(len > res) res = len, dep = depth;
		depth ++;
	}
	cout << res << " " << dep;
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; i ++ ){
		int fa, k, son;
		cin >> fa >> k;
		for(int i = 1; i <= k; i ++ ){
			cin >> son;
			vec[fa].push_back(son);
			st[son] = true;
		}
	}
	int root = 1;
	while(st[root]) root ++;
	bfs(root);
	return 0;
}

1099 Build A Binary Search Tree

分数 30
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

- The left subtree of a node contains only nodes with keys less than the node’s key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
- Both the left and right subtrees must also be binary search trees.

Given the structure of a binary tree and a sequence of distinct integer keys, there is only one way to fill these keys into the tree so that the resulting tree satisfies the definition of a BST. You are supposed to output the level order traversal sequence of that tree. The sample is illustrated by Figure 1 and 2.

在这里插入图片描述

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤100) which is the total number of nodes in the tree. The next N lines each contains the left and the right children of a node in the format left_index right_index, provided that the nodes are numbered from 0 to N−1, and 0 is always the root. If one child is missing, then −1 will represent the NULL child pointer. Finally N distinct integer keys are given in the last line.

Output Specification:
For each test case, print in one line the level order traversal sequence of that tree. All the numbers must be separated by a space, with no extra space at the end of the line.

Sample Input:
9
1 6
2 3
-1 -1
-1 4
5 -1
-1 -1
7 -1
-1 8
-1 -1
73 45 11 58 82 25 67 38 42
Sample Output:
58 25 82 11 38 67 45 73 42

题解
1.构建树
2.将数组排序即为二叉搜索树中序,中序遍历一遍将权值填入树中
3.层序遍历输出

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int N = 100;

int n;
int w[N], cnt;
vector<int>res;

struct node{
	int l, r, val;
}stu[N];

void dfs(int root){
	if(root == -1) return;
	dfs(stu[root].l);
	stu[root].val = w[cnt ++];
	dfs(stu[root].r);
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			res.push_back(stu[Top].val);
		}
	}
	for(int i = 0, len = res.size(); i < len; i ++ ){
		printf("%d%s", res[i], i == len - 1 ? "" : " ");
	}
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		int l, r;
		cin >> l >> r;
		stu[i] = {l, r};
	}
	for(int i = 0; i < n; i ++ ) cin >> w[i];
	sort(w, w + n);
	dfs(0);
	bfs(0);
	return 0;
}

1102 Invert a Binary Tree

The following is from Max Howell @twitter:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
Now it’s your turn to prove that YOU CAN invert a binary tree!

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node from 0 to N−1, and gives the indices of the left and right children of the node. If the child does not exist, a - will be put at the position. Any pair of children are separated by a space.

Output Specification:
For each test case, print in the first line the level-order, and then in the second line the in-order traversal sequences of the inverted tree. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
Sample Output:
3 7 2 6 4 0 5 1
6 5 7 4 3 2 0 1

题解
1.既然要翻转二叉树,那么输入的时候就翻转
2.层序输出和中序遍历输出

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 15;

int n;
bool st[N];
vector<int>res;

struct node{
	int l, r;
}stu[N];

void bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			res.push_back(Top);
		}
	}
	for(int i = 0, len = res.size(); i < len; i ++ ){
		printf("%d%s", res[i], i == len - 1 ? "" : " ");
	}
	printf("\n");
	res.clear();
}

void dfs(int root){
	if(root == -1) return;
	dfs(stu[root].l);
	res.push_back(root);
	dfs(stu[root].r);
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		string a, b;
		cin >> a >> b;
		if(a != "-") stu[i].r = stoi(a), st[stu[i].r] = true;
		else stu[i].r = -1;
		if(b != "-") stu[i].l = stoi(b), st[stu[i].l] = true;
		else stu[i].l = -1;
	}
	int root = 0;
	while(st[root]) root ++;
	bfs(root);
	dfs(root);
	for(int i = 0, len = res.size(); i < len; i ++ ){
		printf("%d%s", res[i], i == len - 1 ? "" : " ");
	}
	return 0;
}

1110 Complete Binary Tree

分数 25
Given a tree, you are supposed to tell if it is a complete binary tree.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤20) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a - will be put at the position. Any pair of children are separated by a space.

Output Specification:
For each case, print in one line YES and the index of the last node if the tree is a complete binary tree, or NO and the index of the root if not. There must be exactly one space separating the word and the number.

Sample Input 1:
9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -
Sample Output 1:
YES 8
Sample Input 2:
8
- -
4 5
0 6
- -
2 3
- 7
- -
- -
Sample Output 2:
NO 1

题解
1.构建树,dfs获得最大深度
2.层序遍历,求最后一个元素,并给每个节点赋上编号(假定是完全二叉树),如果不是最后一层,那么每层节点个数应该是 1 < < d e p t h 1<<{depth} 1<<depth,同时最后一层节点的编号必须从 1 < < d e p t h 1<<{depth} 1<<depth连续增加

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 25;

int n;
int last, depth;
bool flag, st[N];

struct node{
	int l, r, id;
}stu[N];

void bfs(int root){
	vector<int>tem;
	queue<int>que;
	que.push(root);
	int dep = 0;
	stu[root].id = 1;
	while(!que.empty()){
		int len = que.size(), cou = 1 << dep;
		if(dep < depth && len != cou) flag = true;
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(dep == depth) tem.push_back(stu[Top].id);
			if(stu[Top].l != -1) que.push(stu[Top].l), stu[stu[Top].l].id = stu[Top].id * 2;
			if(stu[Top].r != -1) que.push(stu[Top].r), stu[stu[Top].r].id = stu[Top].id * 2 + 1;;
			last = Top;
		}
		dep ++;
	}
	for(int i = 0, ra = (1 << depth), len = tem.size(); i < len; i ++, ra ++){
		if(tem[i] != ra) flag = true;
	}
}

void dfs(int root, int dep){	
	if(root == -1) return;
	depth = max(depth, dep);
	dfs(stu[root].l, dep + 1);
	dfs(stu[root].r, dep + 1);
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ){
		string a, b;
		cin >> a >> b;
		if(a != "-") stu[i].l = stoi(a), st[stu[i].l] = true;
		else stu[i].l = -1;
		if(b != "-") stu[i].r = stoi(b), st[stu[i].r] = true;
		else stu[i].r = -1;
	}
	int root = 0;
	while(st[root]) root ++;
	dfs(root, 0);
	bfs(root);
	if(flag) cout << "NO " << root;
	else cout << "YES " << last;
	return 0;
}

1115 Counting Nodes in a Binary Search Tree

分数 30
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than or equal to the node’s key.
  • The right subtree of a node contains only nodes with keys greater than the node’s key.
  • Both the left and right subtrees must also be binary search trees.

Insert a sequence of numbers into an initially empty binary search tree. Then you are supposed to count the total number of nodes in the lowest 2 levels of the resulting tree.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000) which is the size of the input sequence. Then given in the next line are the N integers in [−1000,1000] which are supposed to be inserted into an initially empty binary search tree.

Output Specification:
For each case, print in one line the numbers of nodes in the lowest 2 levels of the resulting tree in the format:

n1 + n2 = n

where n1 is the number of nodes in the lowest level, n2 is that of the level above, and n is the sum.

Sample Input:
10
25 30 42 16 20 20 35 -5 28 22
Sample Output:
3 + 4 = 7

题解
1.根据给定的无序数组,一个一个插入到BST中去通过dfs
2.递归找到最大深度,并层序遍历得到答案

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 1e3 + 5;

int n, depth;
int n1, n2;
int w[N];

struct node{
	int l, r;
}stu[N];

void get_depth(int root, int dep){
	if(root == -1) return;
	get_depth(stu[root].l, dep + 1);
	get_depth(stu[root].r, dep + 1);
	depth = max(dep, depth);
}

int dfs(int root, int pos){
	if(root == -1){
		stu[pos] = {-1, -1};
		return pos;
	}
	if(w[pos] <= w[root]) stu[root].l = dfs(stu[root].l, pos);
	else stu[root].r = dfs(stu[root].r, pos);
	return root;
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	int dep = 0;
	while(!que.empty()){
		int len = que.size();
		if(dep == depth) n1 = len;
		if(dep == depth - 1) n2 = len;
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
		}
		dep ++;
	}
	printf("%d + %d = %d", n1, n2, n1 + n2);
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) stu[i].l = stu[i].r = -1;
	for(int i = 0; i < n; i ++ ) cin >> w[i];
	for(int i = 1; i < n; i ++ ) dfs(0, i);
	int root = 0;
	get_depth(root, 0);
	bfs(root);
	return 0;
}


1127 ZigZagging on a Tree

分数 30
Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences. And it is a simple standard routine to print the numbers in level-order. However, if you think the problem is too simple, then you are too naive. This time you are supposed to print the numbers in “zigzagging order” – that is, starting from the root, print the numbers level-by-level, alternating between left to right and right to left. For example, for the following tree you must output: 1 11 5 8 17 12 20 15.

在这里插入图片描述

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the inorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print the zigzagging sequence of the tree in a line. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:
8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1
Sample Output:
1 11 5 8 17 12 20 15

题解
1.中序后序建树
2.层序遍历,用flag=true表示逆序存储,反正正序存储

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int N = 35;

int n;
int inorder[N], postorder[N];

struct node{
    int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
    if(l1 >= r1) return -1;
    int val = r1 - 1;
    if(r1 - l1 == 1){
        stu[val] = {-1, -1};
        return val;
    }
    int i = l2;
    while(i < r2 && inorder[i] != postorder[val]) i ++;
    stu[val].l = dfs(l1, l1 + i - l2, l2, i);
    stu[val].r = dfs(l1 + i - l2, r1 - 1, i + 1, r2);
    return val;
}

void bfs(int root){
    vector<int>res;
    queue<int>que;
    que.push(root);
    bool flag = true;
    while(!que.empty()){
        int len = que.size();
        vector<int>tem;
        for(int i = 0; i < len; i ++ ){
            int Top = que.front();que.pop();
            if(stu[Top].l != -1) que.push(stu[Top].l);
            if(stu[Top].r != -1) que.push(stu[Top].r);
            tem.push_back(postorder[Top]);
        }
        if(flag){
            for(int i = tem.size() - 1; i >= 0; i -- ) res.push_back(tem[i]);
        }
        else{
            for(int i = 0, len = tem.size(); i < len; i ++ ) res.push_back(tem[i]);
        }
        flag = !flag;
    }
    for(int i = 0; i < n; i ++ ) printf("%d%s", res[i], i == n - 1 ? "" : " ");
}

int main(){
    cin >> n;
    for(int i = 0; i < n; i ++ ) cin >> inorder[i];
    for(int i = 0; i < n; i ++ ) cin >> postorder[i];
    int root = dfs(0, n, 0, n);
    bfs(root);
    return 0;
}

1138 Postorder Traversal

分数 25
Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and inorder traversal sequences, you are supposed to output the first number of the postorder traversal sequence of the corresponding binary tree.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 50,000), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the first number of the postorder traversal sequence of the corresponding binary tree.

Sample Input:
7
1 2 3 4 5 6 7
2 3 1 5 4 7 6
Sample Output:
3

题解
1.前序中序建树
2.后序遍历树,如果找到了一个不为-1的root,那么直接返回

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 5e4 + 5;

int n;
int preorder[N], inorder[N];

struct node{
    int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
    if(l1 >= r1) return -1;
    int val = l1;
    if(r1 - l1 == 1){
        stu[val] = {-1, -1};
        return val;
    }
    int i = l2;
    while(i < r2 && inorder[i] != preorder[val]) i ++;
    stu[val].l = dfs(l1 + 1, l1 + 1 + i - l2, l2, i);
    stu[val].r = dfs(l1 + 1 + i - l2, r1, i + 1, r2);
    return val;
}

int post_traversal(int root){
    if(root == -1) return -1;
    int Left = post_traversal(stu[root].l);
    if(Left != -1) return Left;
    int Right = post_traversal(stu[root].r);
    if(Right != -1) return Right;
    return root;
}

int main(){
    cin >> n;
    for(int i = 0; i < n; i ++ ) cin >> preorder[i];
    for(int i = 0; i < n; i ++ ) cin >> inorder[i];
    int root = dfs(0, n, 0, n);
    int res = post_traversal(root);
    cout << preorder[res];
    return 0;
}

1151 LCA in a Binary Tree

分数 30
The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.

Given any two nodes in a binary tree, you are supposed to find their LCA.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.

Output Specification:
For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found…

Sample Input:
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99
Sample Output:
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

题解
1.前序中序建树
2.lca进行求解

#include<iostream>
#include<unordered_map>
#include<vector>
#include<queue>

using namespace std;

const int N = 1e4 + 5;

int n, m;
int preorder[N], inorder[N];
unordered_map<int,bool>st;

struct node{
    int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
    if(l1 >= r1) return -1;
    int val = l1;
    if(r1 - l1 == 1){
        stu[val] = {-1, -1};
        return val;
    }
    int i = l2;
    while(i < r2 && inorder[i] != preorder[val]) i ++;
    stu[val].l = dfs(l1 + 1, l1 + 1 + i - l2, l2, i);
    stu[val].r = dfs(l1 + 1 + i - l2, r1, i + 1, r2);
    return val;
}

int get_lca(int root, int a, int b){
    if(root == -1 || preorder[root] == a || preorder[root] == b) return root;
    int Left = get_lca(stu[root].l, a, b);
    int Right = get_lca(stu[root].r, a, b);
    if(Left != -1 && Right != -1) return root;
    if(Left != -1) return Left;
    if(Right != -1) return Right;
    return -1;
}

int main(){
    cin >> m >> n;
    for(int i = 0; i < n; i ++ ) cin >> inorder[i];
    for(int i = 0; i < n; i ++ ) cin >> preorder[i];
    for(int i = 0; i < n; i ++ ) st[inorder[i]] = true;
    int root = dfs(0, n, 0, n);
    while(m -- ){
        int a, b;
        cin >> a >> b;
        if(!st[a] &&!st[b]) printf("ERROR: %d and %d are not found.\n", a, b);
        else if(!st[a]) printf("ERROR: %d is not found.\n", a);
        else if(!st[b]) printf("ERROR: %d is not found.\n", b);
        else{
            int lca = get_lca(root, a, b);
            lca = preorder[lca];
            if(lca == a) printf("%d is an ancestor of %d.\n", lca, b);
            else if(lca == b) printf("%d is an ancestor of %d.\n", lca, a);
            else printf("LCA of %d and %d is %d.\n", a, b, lca);
        }
    }
    return 0;
}

1147 Heaps

分数 30
In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is either greater than or equal to (in a max heap) or less than or equal to (in a min heap) the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree. (Quoted from Wikipedia at https://en.wikipedia.org/wiki/Heap_(data_structure))

Your job is to tell if a given complete binary tree is a heap.

Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 100), the number of trees to be tested; and N (1 < N ≤ 1,000), the number of keys in each tree, respectively. Then M lines follow, each contains N distinct integer keys (all in the range of int), which gives the level order traversal sequence of a complete binary tree.

Output Specification:
For each given tree, print in a line Max Heap if it is a max heap, or Min Heap for a min heap, or Not Heap if it is not a heap at all. Then in the next line print the tree’s postorder traversal sequence. All the numbers are separated by a space, and there must no extra space at the beginning or the end of the line.

Sample Input:
3 8
98 72 86 60 65 12 23 50
8 38 25 58 52 82 70 60
10 28 15 12 34 9 8 56
Sample Output:
Max Heap
50 60 65 72 12 23 86 98
Min Heap
60 58 52 38 82 70 25 8
Not Heap
56 12 34 28 9 8 15 10

题解
1.如果是大根堆,那么down操作应该无法实现,毕竟都已经从大到小了
2.如果是小根堆,那么up操作应该无法实现,毕竟都已经从小到大了
3.后序遍历并输出

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 1e3 + 5;

int n, m;
int heap[N];

struct node{
    int l, r;
}stu[N];

bool down(int root){
    if(root * 2 <= m && heap[root] < heap[root * 2]) return true;
    if(root * 2 + 1 <= m && heap[root] < heap[root * 2 + 1]) return true;
    return false;
}

bool up(int root){
    if(root / 2 && heap[root] < heap[root / 2]) return true;
    return false;
}

void dfs(int root, vector<int>&res){
    if(root == -1) return;
    dfs(stu[root].l, res);
    dfs(stu[root].r, res);
    res.push_back(heap[root]);
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= m; i ++ ){
        if(i * 2 <= m) stu[i].l = i * 2;
        else stu[i].l = -1;
        if(i * 2 + 1 <= m) stu[i].r = i * 2 + 1;
        else stu[i].r = -1;
    }
    while(n -- ){
        for(int i = 1; i <= m; i ++ ) cin >> heap[i];
        bool flag = false;
        vector<int>res;
        if(heap[1] > heap[2]){
            for(int i = 1; i <= m; i ++ ){
                if(down(i)){
                    flag = true;
                    break;
                }
            }
            if(flag) cout << "Not Heap\n";
            else cout << "Max Heap\n";
        }
        else{
            for(int i = 1; i <= m; i ++ ){
                if(up(i)){
                    flag = true;
                    break;
                }
            }
            if(flag) cout << "Not Heap\n";
            else cout << "Min Heap\n";
        }
        dfs(1, res);
        for(int i = 0, len = res.size(); i < len; i ++ ){
            printf("%d%s", res[i], i == len - 1 ? "" : " ");
        }
        printf("\n");
    }
    return 0;
}

1155 Heap Paths

分数 30
In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is either greater than or equal to (in a max heap) or less than or equal to (in a min heap) the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree. (Quoted from Wikipedia at https://en.wikipedia.org/wiki/Heap_(data_structure))

One thing for sure is that all the keys along any path from the root to a leaf in a max/min heap must be in non-increasing/non-decreasing order.

Your job is to check every path in a given complete binary tree, in order to tell if it is a heap or not.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (1<N≤1,000), the number of keys in the tree. Then the next line contains N distinct integer keys (all in the range of int), which gives the level order traversal sequence of a complete binary tree.

Output Specification:
For each given tree, first print all the paths from the root to the leaves. Each path occupies a line, with all the numbers separated by a space, and no extra space at the beginning or the end of the line. The paths must be printed in the following order: for each node in the tree, all the paths in its right subtree must be printed before those in its left subtree.

Finally print in a line Max Heap if it is a max heap, or Min Heap for a min heap, or Not Heap if it is not a heap at all.

Sample Input 1:
8
98 72 86 60 65 12 23 50
Sample Output 1:
98 86 23
98 86 12
98 72 65
98 72 60 50
Max Heap
Sample Input 2:
8
8 38 25 58 52 82 70 60
Sample Output 2:
8 25 70
8 25 82
8 38 52
8 38 58 60
Min Heap
Sample Input 3:
8
10 28 15 12 34 9 8 56
Sample Output 3:
10 15 8
10 15 9
10 28 34
10 28 12 56
Not Heap

题解
1.dfs遍历一遍记录所有从根节点到叶子结点的路径
2.如果是大根堆,那么down操作应该无法实现,毕竟都已经从大到小了
3.如果是小根堆,那么up操作应该无法实现,毕竟都已经从小到大了

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 1e3 + 5;

int m;
int heap[N];
vector<vector<int>>res;
vector<int>tem;

struct node{
    int l, r;
}stu[N];

bool down(int root){
    if(root * 2 <= m && heap[root] < heap[root * 2]) return true;
    if(root * 2 + 1 <= m && heap[root] < heap[root * 2 + 1]) return true;
    return false;
}

bool up(int root){
    if(root / 2 && heap[root] < heap[root / 2]) return true;
    return false;
}

int dfs(int root){
    if(root == -1) return -1;
    tem.push_back(heap[root]);
    int Right = dfs(stu[root].r);
    tem.pop_back();
    tem.push_back(heap[root]);
    int Left = dfs(stu[root].l);
    if(Left == -1 && Right == -1) res.push_back(tem);
    tem.pop_back();
    return root;
}

int main(){
    cin >> m;
    for(int i = 1; i <= m; i ++ ){
        if(i * 2 <= m) stu[i].l = i * 2;
        else stu[i].l = -1;
        if(i * 2 + 1 <= m) stu[i].r = i * 2 + 1;
        else stu[i].r = -1;
    }   
    for(int i = 1; i <= m; i ++ ) cin >> heap[i];
    bool flag = false;
    dfs(1);
    for(int i = 0, len = res.size(); i < len; i ++ ){
        for(int j = 0, len1 = res[i].size(); j < len1; j ++ ){
            printf("%d%s", res[i][j], j == len1 - 1 ? "" : " ");
        }
        printf("\n");
    }
    if(heap[1] > heap[2]){
        for(int i = 1; i <= m; i ++ ){
            if(down(i)){
                flag = true;
                break;
            }
        }
        if(flag) cout << "Not Heap\n";
        else cout << "Max Heap\n";
    }
    else{
        for(int i = 1; i <= m; i ++ ){
            if(up(i)){
                flag = true;
                break;
            }
        }
        if(flag) cout << "Not Heap\n";
        else cout << "Min Heap\n";
    }
    return 0;
}

1159 Structure of a Binary Tree

分数 30
Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.

Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:

  • A is the root
  • A and B are siblings
  • A is the parent of B
  • A is the left child of B
  • A is the right child of B
  • A and B are on the same level
  • It is a full tree

Note:

  • Two nodes are on the same level, means that they have the same depth.
  • A full binary tree is a tree in which every node other than the leaves has two children.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than 1 0 3 10^3 103
and are separated by a space.

Then another positive integer M (≤30) is given, followed by M lines of statements. It is guaranteed that both A and B in the statements are in the tree.

Output Specification:
For each statement, print in a line Yes if it is correct, or No if not.

Sample Input:
9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree
Sample Output:
Yes
No
Yes
No
Yes
Yes
Yes

题解
1.后序中序建树,同时更新每个节点的双亲,深度
2.层序遍历一遍,如果某个节点只有单个孩子,说明不是full
3.然后根据map映射后,进行测试点的相关判断并输出

#include<iostream>
#include<unordered_map>
#include<vector>
#include<queue>

using namespace std;

const int N = 35;

int n, m;
int postorder[N], inorder[N];

struct node{
	int l, r, parent, dep;
}stu[N];

unordered_map<int,int>mp;

int dfs(int l1, int r1, int l2, int r2, int parent, int dep){
	if(l1 >= r1) return -1;
	int val = r1 - 1;
	if(r1 - l1 == 1){
		stu[val] = {-1, -1, parent, dep};
		return val;
	}
	int i = l2;
	while(i < r2 && postorder[val] != inorder[i]) i ++;
	int Left = dfs(l1, l1 + i - l2, l2, i, val, dep + 1);
	int Right = dfs(l1 + i - l2, r1 - 1, i + 1, r2, val, dep + 1);
	stu[val] = {Left, Right, parent, dep};
	return val;
}

bool bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			if((stu[Top].l != -1 && stu[Top].r == -1) || (stu[Top].l == -1 && stu[Top].r != -1)) return false;
		}
	}
	return true;
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> postorder[i], mp[postorder[i]] = i;
	for(int i = 0; i < n; i ++ ) cin >> inorder[i];
	int root = dfs(0, n, 0, n, -1, 0);
	bool Full = bfs(root);
	cin >> m;
	while(m -- ){
		string s;
		cin >> s;
		if(s == "It"){
			cin >> s >> s >> s >> s;
			printf("%s\n", Full == true ? "Yes" : "No");
		}
		else{
			int A = stoi(s);
			cin >> s >> s;
			if(s == "the"){
				cin >> s;
				if(s == "root") printf("%s\n", root == mp[A] ? "Yes" : "No");
				else{
					if(s == "parent"){
						cin >> s >> s;
						int B = stoi(s);
						printf("%s\n", stu[mp[B]].parent == mp[A] ? "Yes" : "No");
					}
					else if(s == "left"){
						cin >> s >> s >> s;
						int B = stoi(s);
						printf("%s\n", stu[mp[B]].l == mp[A] ? "Yes" : "No");
					}
					else{
						cin >> s >> s >> s;
						int B = stoi(s);
						printf("%s\n", stu[mp[B]].r == mp[A] ? "Yes" : "No");
					}
				}
			}
			else{
				int B = stoi(s);
				cin >> s >> s;
				if(s == "siblings") printf("%s\n", stu[mp[B]].parent == stu[mp[A]].parent ? "Yes" : "No");
				else{
					cin >> s >> s >> s;
					printf("%s\n", stu[mp[B]].dep == stu[mp[A]].dep ? "Yes" : "No");
				}
			}
		}
	}
	return 0;
}

1167 Cartesian Tree

分数 30
A Cartesian tree is a binary tree constructed from a sequence of distinct numbers. The tree is heap-ordered, and an inorder traversal returns the original sequence. For example, given the sequence { 8, 15, 3, 4, 1, 5, 12, 10, 18, 6 }, the min-heap Cartesian tree is shown by the figure.

在这里插入图片描述

Your job is to output the level-order traversal sequence of the min-heap Cartesian tree.

Input Specification:
Each input file contains one test case. Each case starts from giving a positive integer N (≤30), and then N distinct numbers in the next line, separated by a space. All the numbers are in the range of int.

Output Specification:
For each test case, print in a line the level-order traversal sequence of the min-heap Cartesian tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line.

Sample Input:
10
8 15 3 4 1 5 12 10 18 6
Sample Output:
1 3 5 8 4 6 15 10 12 18

题解
1.根据中序,找到每次[l, r)中最小值的位置,分别递归左右两边建树
2.层序输出

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 35;

int n;
int inorder[N];
vector<int>res;

struct node{
	int l, r;
}stu[N];

int dfs(int l, int r){
	if(l >= r) return -1;
	int pos = l;
	if(r - l == 1){
		stu[pos] = {-1, -1};
		return l;
	}
	for(int i = l + 1; i < r; i ++ ) pos = inorder[pos] > inorder[i] ? i : pos;
	stu[pos].l = dfs(l, pos);
	stu[pos].r = dfs(pos + 1, r);
	return pos;
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			res.push_back(inorder[Top]);
		}
	}
	for(int i = 0, len = res.size(); i < len; i ++ ) printf("%d%s", res[i], i == len - 1 ? "" : " ");
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> inorder[i];
	int root = dfs(0, n);
	bfs(root);
	return 0;
}

1174 Left-View of Binary Tree

分数 25
The left-view of a binary tree is a list of nodes obtained by looking at the tree from left hand side and from top down. For example, given a tree shown by the figure, its left-view is { 1, 2, 3, 4, 5 }

在这里插入图片描述

Given the inorder and preorder traversal sequences of a binary tree, you are supposed to output its left-view.

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20), which is the total number of nodes in the tree. Then given in the following 2 lines are the inorder and preorder traversal sequences of the tree, respectively. All the keys in the tree are distinct positive integers in the range of int.

Output Specification:
For each case, print in a line the left-view of the tree. All the numbers in a line are separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:
8
2 3 1 5 4 7 8 6
1 2 3 6 7 4 5 8
Sample Output:
1 2 3 4 5

题解
1.前序中序建树
2.层序遍历取出每一层的第一个的即为左视图

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 25;

int n;
int preorder[N], inorder[N];
vector<int>res;

struct node{
	int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
	if(l1 >= r1) return -1;
	int val = l1;
	if(r1 - l1 == 1){
		stu[val] = {-1, -1};
		return val;
	}
	int i = l2;
	while(i < r2 && preorder[val] != inorder[i]) i ++;
	stu[val].l = dfs(l1 + 1, l1 + 1 + i - l2, l2, i);
	stu[val].r = dfs(l1 + 1 + i - l2, r1, i + 1, r2);
	return val;
}

void bfs(int root){
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int len = que.size();
		for(int i = 0; i < len; i ++ ){
			int Top = que.front();que.pop();
			if(stu[Top].l != -1) que.push(stu[Top].l);
			if(stu[Top].r != -1) que.push(stu[Top].r);
			if(!i) res.push_back(preorder[Top]);
		}
	}
	for(int i = 0, len = res.size(); i < len; i ++ ) printf("%d%s", res[i], i == len - 1 ? "" : " ");
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> inorder[i];
	for(int i = 0; i < n; i ++ ) cin >> preorder[i];
	int root = dfs(0, n, 0, n);
	bfs(root);
	return 0;
}

1130 Infix Expression

分数 25
Given a syntax tree (binary), you are supposed to output the corresponding infix expression, with parentheses reflecting the precedences of the operators.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 20) which is the total number of nodes in the syntax tree. Then N lines follow, each gives the information of a node (the i-th line corresponds to the i-th node) in the format:

data left_child right_child

where data is a string of no more than 10 characters, left_child and right_child are the indices of this node’s left and right children, respectively. The nodes are indexed from 1 to N. The NULL link is represented by −1. The figures 1 and 2 correspond to the samples 1 and 2, respectively.
在这里插入图片描述

Output Specification:
For each case, print in a line the infix expression, with parentheses reflecting the precedences of the operators. Note that there must be no extra parentheses for the final expression, as is shown by the samples. There must be no space between any symbols.

Sample Input 1:
8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1
Sample Output 1:
(a+b)*(c*(-d))
Sample Input 2:
8
2.35 -1 -1
 * 6 1
 * -1 4
% 7 8
 * 2 3
a -1 -1
str -1 -1
871 -1 -1
Sample Output 2:
(a*2.35)+(-(str%871))

题解
1.dfs进行后序遍历:

  • 如果是叶子节点,直接返回该节点的op
  • 如果该节点的左儿子不是叶子结点,就给一个()
  • 如果该节点的右儿子不是叶子节点,就给一个()
  • 输出 r e t u r n = L e f t + o p + R i g h t return = Left + op + Right return=Left+op+Right
#include<iostream>

using namespace std;

const int N = 25;

int n;
bool st[N], leaves[N];

struct node{
	int l, r;
	string op;
}stu[N];

string dfs(int root){
	string Left, Right;
	Left = Right = "";
	if(stu[root].l != -1){
		Left = dfs(stu[root].l);
		if(!leaves[stu[root].l]) Left = "(" + Left + ")";
	} 
	if(stu[root].r != -1){
		Right = dfs(stu[root].r);
		if(!leaves[stu[root].r]) Right = "(" + Right + ")";
	} 
	return Left + stu[root].op + Right;
}

int main(){
	cin >> n;
	for(int i = 1; i <= n; i ++ ){
		string op;
		int a, b;
		cin >> op >> a >> b;
		stu[i] = {a, b, op};
		if(a != -1) st[a] = true;
		if(b != -1) st[b] = true;
		if(a == -1 && b == -1) leaves[i] = true;
	}
	int root = 1;
	while(st[root]) root ++;
	cout << dfs(root);
	return 0;
}

1162 Postfix Expression

分数 25
Given a syntax tree (binary), you are supposed to output the corresponding postfix expression, with parentheses reflecting the precedences of the operators.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 20) which is the total number of nodes in the syntax tree. Then N lines follow, each gives the information of a node (the i-th line corresponds to the i-th node) in the format:

data left_child right_child

where data is a string of no more than 10 characters, left_child and right_child are the indices of this node’s left and right children, respectively. The nodes are indexed from 1 to N. The NULL link is represented by −1. The figures 1 and 2 correspond to the samples 1 and 2, respectively.
在这里插入图片描述

Output Specification:
For each case, print in a line the postfix expression, with parentheses reflecting the precedences of the operators.There must be no space between any symbols.

Sample Input 1:
8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1
Sample Output 1:
(((a)(b)+)((c)(-(d))*)*)
Sample Input 2:
8
2.35 -1 -1
* 6 1
- -1 4
% 7 8
+ 2 3
a -1 -1
str -1 -1
871 -1 -1
Sample Output 2:
(((a)(2.35)*)(-((str)(871)%))+)

题解
1.dfs进行后序遍历:

  • 如果该节点只有右儿子,说明是负号,输出 r e t u r n = “ ( ” + o p + R i g h t + “ ) ” return = “(” + op + Right + “)” return=(+op+Right+)
  • 否则无论该节点是叶子节点还是有二胎的节点,都 r e t u r n = “ ( ” + L e f t + R i g h t + o p + “ ) " return =“(” + Left + Right + op + “)" return=(+Left+Right+op+)"
#include<iostream>

using namespace std;

const int N = 25;

int n;
bool st[N];

struct node{
	int l, r;
	string op;
}stu[N];

string dfs(int root){
	string Left, Right;
	Left = Right = "";
	if(stu[root].l != -1) Left = dfs(stu[root].l);
	if(stu[root].r != -1) Right = dfs(stu[root].r);
	if(stu[root].l == -1 && stu[root].r != -1) return "(" + stu[root].op + Right + ")";
	return "(" + Left + Right + stu[root].op + ")";
}

int main(){
	cin >> n;
	for(int i = 1; i <= n; i ++ ){
		string op;
		int a, b;
		cin >> op >> a >> b;
		stu[i] = {a, b, op};
		if(a != -1) st[a] = true;
		if(b != -1) st[b] = true;
	}
	int root = 1;
	while(st[root]) root ++;
	cout << dfs(root);
	return 0;
}

1119 Pre- and Post-order Traversals

分数 30
Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 30), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:
For each test case, first printf in a line Yes if the tree is unique, or No if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input 1:
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
Sample Output 1:
Yes
2 1 6 4 7 3 5
Sample Input 2:
4
1 2 3 4
2 4 3 1
Sample Output 2:
No
2 1 3 4

题解
1.前序后序建树
2.如果某个节点只有一个儿子,那么这棵树就不唯一
3.最后答案输出中序的时候,最后需要换行,不换行会显示格式错误

#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 35;

int n;
bool flag;
int preorder[N], postorder[N];
vector<int>res;

struct node{
	int l, r;
}stu[N];

int dfs(int l1, int r1, int l2, int r2){
	if(l1 >= r1) return -1;
	int val = l1;
	if(r1 - l1 == 1){
		stu[val] = {-1, -1};
		return val;
	}
	int i = l2;
	while(i < r2 && preorder[val + 1] != postorder[i]) i ++;
	i ++;
	int Left = dfs(l1 + 1, l1 + 1 + i - l2, l2, i);
	int Right = dfs(l1 + 1 + i - l2, r1, i, r2 - 1);
	if((Left == -1 && Right != -1) || (Left != -1 && Right == -1)) flag = true;
	stu[val] = {Left, Right};
	return val;
}

void inorder_traversal(int root){
	if(root == -1) return;
	inorder_traversal(stu[root].l);
	res.push_back(preorder[root]);
	inorder_traversal(stu[root].r);
}

int main(){
	cin >> n;
	for(int i = 0; i < n; i ++ ) cin >> preorder[i];
	for(int i = 0; i < n; i ++ ) cin >> postorder[i];
	int root = dfs(0, n, 0, n);
	inorder_traversal(root);
	printf("%s\n", flag == true ? "No" : "Yes");
	for(int i = 0; i < n; i ++ ) printf("%d%s", res[i], i == n - 1 ? "\n" : " ");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值