赞
踩
- Traversalsn. /trəˈvərs(ə)l/ [计] 遍历;横越;横断物
- distinct /dɪˈstɪŋkt/ adj. 明显的;独特的
- sequences 美 /ˈsiːkwənsɪz/ n. 数 序列,顺序;
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.
假设二叉树中的所有键都是不同的正整数。给定了postorder和inorder遍历序列,您应该输出相应二叉树的level order遍历序列。
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.
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.
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
4 1 6 3 5 7 2
// // Created by jiayadong on 2020/8/27. // /** *后序+前序= */ #include <iostream> #include <queue> using namespace std; const int maxn=50; struct node{ int data; node* lchild; node* rchild; }; //设置全局变量,先序数组,中序数组,后序数组 int pre[maxn],in[maxn],post[maxn]; int n; //结点个数 //当前二叉树的后序序列区间为[posL,posR],中序序列区间为[intL ,inR]; /** * * @param posL 后序左 * @param postR 后序右 * @param inL 中序左 * @param inR 中序右 * @return */ node *create(int postL,int postR, int inL,int inR) { // 递归边界 if (postL>postR){ return NULL; } // 申请一个根节点,用来存放 node* root=new node; root->data=post[postR]; // 开始寻找左右子树个数 int k; for (k = inL; k <=inR ; k++) { if (in[k]==post[postR]){ break; } } // 中序序列找出左右子树个数 int numLeft=k-inL; root->lchild = create(postL,postL+numLeft-1,inL,k-1); root->rchild = create(postL+numLeft,postR-1,k+1,inR); // 返回根节点 return root; } //已经输出根节点个数 int num= 0; // 层序遍历 void BFS(node* root) { queue<node*> q; //这里队列放的是地址 q.push(root); while (!q.empty()){ node *now=q.front(); q.pop(); num++; cout<<now->data; if (num<n) cout<<" "; if (now->lchild!=NULL) q.push(now->lchild); if (now->rchild!=NULL) q.push(now->rchild); } } int main(){ cin>>n; for(int i=0;i<n;i++) { cin>>post[i]; } for(int i=0;i<n;i++) { cin>>in[i]; } node *root=create(0,n-1,0,n-1); // 建树 BFS(root); return 0; }
Given a non-empty tree with root R, and with weight W**i assigned to each tree node T**i. 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.
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<230, the given weight number. The next line contains N positive numbers where W**i (<1000) corresponds to the tree node T**i. 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
.
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 {A1,A2,⋯,A**n} is said to be greater than sequence {B1,B2,⋯,B**m} if there exists 1≤k<min{n,m} such that A**i=B**i for i=1,⋯,k, and A**k+1>B**k+1.
20 9 24
//结点树 非叶子结点 常数S
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
10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2
Special thanks to Zhang Yuan and Yang Han for their contribution to the judge’s data.
// // Created by jiayadong on 2020/8/28. // /** * 注意点:<br> * <li>1.有多条路径时,有更高全值的路径应该先输出.由于在读入时已经对每个节点所有子节点按权值从大到小排序 * <li>所以在递归过程中总是会先访问所有子节点中权值更大的 * <li>2. * */ #include <iostream> #include <vector> #include <algorithm> using namespace std; const int maxn=100010; struct node{ int weight; //权重 vector<int> child; //指针域 }Node[maxn]; //要有一个比较函数 bool cmp(int a,int b) { // 按结点数据域从大到小排序 return Node[a].weight>Node[b].weight; } /** * 一些全局变量 * */ //结点,边数,给定的和 int n,m,s; int path[maxn]; //记录路径 /** * * @param index 当前访问结点为index * @param numNode numNode为当前路径path上的结点个数 * @param sum sum */ void DFS(int index, int numNode,int sum) { if (sum>s) return; if (sum==s) { if (Node[index].child.size()!=0) return; // 满足条件 for(int i=0;i<numNode;i++) { cout<<Node[path[i]].weight; if (i<numNode-1) cout<<" "; else cout<<endl; } return; } // 枚举所有子节点 for(int i=0;i<Node[index].child.size();i++) { int child=Node[index].child[i]; path[numNode]=child; // 遍历孩子结点,将层数加一 DFS(child,numNode + 1,sum + Node[child].weight); } } int main(){ cin>>n>>m>>s; for(int i=0;i<n;i++) { cin>>Node[i].weight; } // id为结点, k为孩子个数 int id,k,child; for(int i=0;i<m;i++) { cin>>id>>k; for(int j=0;j<k;j++) { // child为结点为id的孩子 cin>>child; Node[id].child.push_back(child); } // 接收了一个结点的孩子,再让这个整个孩子进行排序 sort(Node[id].child.begin(),Node[id].child.end(),cmp); //排序 } path[0]=0; //路径第一个结点设置为0号结点 // 此时的结点个数是第一个结点,而且结点个数为1,为0号结点个数 DFS(0,1,Node[0].weight); //DFS求解 return 0; }
recursively 英 /ri’kəsivli/ adv. 递归地;递回地
Mirror Image 镜像
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
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.
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.
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.
7
8 6 5 7 10 8 11
YES
5 7 6 8 11 10 8
7
8 10 11 8 6 7 5
YES
11 8 10 7 5 6 8
7
8 6 8 5 10 9 11
NO
判断给出的序列是不是
二叉排序树的先序序列或者是镜像二叉排序树的先序序列
二叉树的遍历主要有三种:
(1)先(根)序遍历(根左右)
(2)中(根)序遍历(左根右)
(3)后(根)序遍历(左右根)
guaranteed n. 保证;担保;保证人;保证书;抵押品
alphabetical adj. 字母的;[计] 依字母顺序的
cluster
One way that the police finds the head of a gang is to check people’s phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made between the two persons. A “Gang” is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threshold K. In each gang, the one with maximum total weight is the head. Now given a list of phone calls, you are supposed to find the gangs and the heads.
Each input file contains one test case. For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threthold, respectively. Then N lines follow, each in the following format:
Name1 Name2 Time
where Name1
and Name2
are the names of people at the two ends of the call, and Time
is the length of the call. A name is a string of three capital letters chosen from A
-Z
. A time length is a positive integer which is no more than 1000 minutes.
For each test case, first print in a line the total number of gangs. Then for each gang, print in a line the name of the head and the total number of the members. It is guaranteed that the head is unique for each gang. The output must be sorted according to the alphabetical order of the names of the heads.
8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10
2
AAA 3
GGG 3
8 70
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10
0
注:可以定义map<string,int> 来建立团伙头目和姓名和团伙成员人数的映射关系.由于map中元素自动按键值从小到大排序,可以自动满足题目了题目要求的"姓名字典从小到大输出"的规定
本题可以使用并查集解决,在使用并查集时,要注意合并函数中需要总是保持点权更大的结点为集合的根结点
我们还需要设置两个数组
1.用来存放以当前结点为根结点的集合的总边权
2.另一个数组用来存放以当前结点为根结点的集合的成员人数
这一套函数下来简直像艺术品一样
// // Created by jiayadong on 2020/8/30. // /** * 这个题是关于什么的? * 每一个连通分量的路径长度大于K * 并且找出他们的头目以及成员个数 * 即起点个数和总结点个数 */ #include <iostream> #include <string> #include <map> #include <cstring> using namespace std; const int maxn=2010; //总人数 const int INF=1000000000; //无穷大 /** * */ map<int ,string> intToString; //编号->姓名 map<string , int> stringToInt; //姓名->编号 map<string , int> Gang; // head->人数 //邻接矩阵G,点权值为weight int G[maxn][maxn] = {0} , weight[maxn] = {0}; //边数n,下限k,总人数numPerson int n, k , numPerson = 0; //标记是否被访问 bool vis[maxn] ={false}; /** * * @param nowVisit 当前访问的编号 * @param head 头目 * @param numMember 成员编号 * @param totalValue 连通快的总边权 */ void DFS(int nowVisit, int& head,int& numMember, int& totalValue) { // 一个连通遍历里的人数 numMember++; vis[nowVisit] = true; if(weight[nowVisit] > weight[head]) { head=nowVisit; } // 枚举所有人 for(int i=0;i<numPerson;i++) { // 如果从nowVisit能到达i if (G[nowVisit][i] > 0){ totalValue += G[nowVisit][i] ; // 删除这条边,防止 G[nowVisit][i] =G[i][nowVisit] =0; if ( vis[i] == false ) { DFS(i,head,numMember , totalValue ); } } } } /** * 函数遍历整个图,获取每个连通块的信息 */ void DFSTrave() { for(int i=0;i<numPerson;i++) { if (vis[i] == false) { // 头目,成员数,总边权 int head = i, numMember = 0,totalValue = 0; // 遍历i所在的连通块 DFS(i , head , numMember , totalValue); // 如果成员数大于2且总边权大于k,head人数为numMember if (numMember >2 && totalValue > k) { Gang[ intToString[head]] = numMember; } } } } // int change(string str) { if (stringToInt.find(str) != stringToInt.end()) { return stringToInt[str]; } else{ // str的编号为numPerson,numPerson对应str stringToInt[str] = numPerson; intToString[numPerson] = str; return numPerson++; } } int main(){ int w; string str1 , str2; cin>>n>>k; for(int i=0;i < n;i++) { cin >>str1 >>str2 >>w; int id1 = change(str1); int id2 = change(str2); weight[id1] += w; weight[id2] += w; G[id1][id2] +=w; //边id1->id2的边权增加w G[id2][id1] +=w; //边id2->id1的边权增加w } DFSTrave(); //遍历整个图的所有连通块,获取Gang的信息 cout <<Gang.size() <<endl; for (auto it = Gang.begin(); it!=Gang.end() ; it++) { cout<<it->first <<" "<<it->second <<endl; } return 0; }
Forwards
potential adj. 潜在的,可能的;势的
specific user adj:特殊的用户
Hence adv. 因此;今后
guaranteed v. 保证;提供(产品)保修单;
initial adj. 最初的;字首的
Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well. Hence a social network is formed with followers relations. When a user makes a post on Weibo, all his/her followers can view and forward his/her post, which can then be forwarded again by their followers. Now given a social network, you are supposed to calculate the maximum potential amount of forwards for any specific user, assuming that only L levels of indirect followers are counted.
Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤1000), the number of users; and L (≤6), the number of levels of indirect followers that are counted. Hence it is assumed that all the users are numbered from 1 to N. Then N lines follow, each in the format:
M[i] user_list[i]
where M[i]
(≤100) is the total number of people that user[i]
follows; and user_list[i]
is a list of the M[i]
users that followed by user[i]
. It is guaranteed that no one can follow oneself. All the numbers are separated by a space.
Then finally a positive K is given, followed by K UserID
's for query.
翻译一下:
614/5000
每个输入文件包含一个测试用例。 对于每种情况,第一行包含2个正整数:N(≤1000),用户数; L(≤6),即被计数的间接关注者的级别数。 因此,假定所有用户的编号都从1到N。然后是N行,每行的格式为:
其中M [i](≤100)是用户[i]跟随的总人数; 和user_list [i]是M [i]个用户列表,后跟user [i]。 保证没有人可以跟随自己。 所有数字都用空格分隔。
然后,最后给出一个正数K,后跟K个用户ID进行查询。
For each UserID
, you are supposed to print in one line the maximum potential amount of forwards this user can trigger, assuming that everyone who can view the initial post will forward it once, and that only L levels of indirect followers are counted.
对于每个UserID,假设每个可以查看初始帖子的用户都将转发一次,并且只计算L级间接关注者,则应该在一行中打印出该用户可以触发的最大潜在转发量。
7 3
3 2 3 4
0
2 5 6
2 3 1
2 3 4
1 4
1 5
2 2 6
4
5
在clion中处理的时候,出现了数据问题,DEV和oj上没有这种问题出现
// // Created by jiayadong on 2020/8/31. // #include <iostream> #include <queue> #include <vector> #include <cstring> using namespace std; const int maxn=2001; struct Node{ int v; //结点编号 int layer; //结点层号 }; vector<Node> Adj[maxn]; bool vis[maxn] ={false}; /** * * @param s 结点编号 * @param L 层数限制 * @return */ int BFS(int s,int L) { int numForward = 0; //转发数 queue<Node> q; Node start; start.v=s; start.layer=0; q.push(start); vis[start.v] = true; while (!q.empty()) { // 取出队首元素 Node Top=q.front(); q.pop(); int u=Top.v; for(int i=0;i<Adj[u].size();i++) { Node next=Adj[u][i]; next.layer = Top.layer+1; if (vis[next.v] == false && next.layer <= L){ q.push(next); vis[next.v] = true; numForward++; //转发数加1 } } } return numForward; //返回转发数数字 } int main(){ Node user; int n,L,numFollow,idFollow; cin>>n>>L; for(int i=1;i<=n;i++) { user.v=i; //用户编号为i cin>> numFollow; for(int j =0;j<numFollow; j++) { cin>>idFollow; //i号用户关注的用户编号 Adj[idFollow].push_back(user); //边idFollow->i } } int numQuery, s; cin>>numQuery; for(int i=0;i<numQuery;i++) { // 因为要使用两次,所以一些数组要进行初始化 memset(vis, false , sizeof(vis)); cin>>s; cout<< BFS(s,L)<<endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。