1. 数叶子结点
题目链接:数叶子结点
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
const int M = N * N;
int h[N], e[M], ne[M], idx;
int cnt[N], height;
int n, m;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u, int depth)
{
if (h[u] == -1)
{
height = max(height, depth);
cnt[depth]++;
return;
}
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
dfs(j, depth + 1);
}
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++)
{
int id, k;
cin >> id >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
add(id, x);
}
}
dfs(1, 1);
for (int i = 1; i <= height; i++)
cout << cnt[i] << ' ';
return 0;
}
2. 树的遍历
题目链接:树的遍历
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
int pos[N], in[N];
int n;
typedef struct node
{
int data;
node* left, * right;
}node, *tree;
tree create(int len, int* in, int *pos)
{
if (len <= 0)return nullptr;
tree T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = pos[len - 1];
int i = 0;
for (i = 0; i < len; i++)
if (T->data == in[i])
break;
T->left = create(i, in, pos);
T->right = create(len - i - 1, in + i + 1, pos + i);
return T;
}
void level_pos(tree T)
{
queue<tree>q;
q.push(T);
while (q.size())
{
auto t = q.front();
cout << t->data << ' ';
q.pop();
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> pos[i];
for (int i = 0; i < n; i++)cin >> in[i];
tree T = create(n, in, pos);
level_pos(T);
return 0;
}
3. 最深的根
题目链接:最深的根 并查集合并,并且求连通块的个数 递归求树的高度即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
const int M = N * N;
int h[N], e[M], ne[M], idx;
int n;
int height_max;
int f[N];
int res;
vector<int>ans;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int find(int x)
{
if (x != f[x])f[x] = find(f[x]);
return f[x];
}
int dfs(int u, int father)
{
int depth = 0;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == father)continue;
depth = max(depth, dfs(j, u) + 1);
}
return depth;
}
int main()
{
memset(h, -1, sizeof h);
for (int i = 0; i < N; i++)f[i] = i;
cin >> n;
for (int i = 0; i < n - 1; i++)
{
int a, b;
cin >> a >> b;
if (find(a) != find(b))
f[find(a)] = find(b);
add(a, b), add(b, a);
}
for (int i = 1; i <= n; i++)
if (f[i] == i)res++;
if (res >= 2)
printf("Error: %d components", res);
else
{
for (int i = 1; i <= n; i++)
{
int height = dfs(i, -1);
if (height > height_max)
{
height_max = height;
ans.clear();
ans.push_back(i);
}
else if (height == height_max)
ans.push_back(i);
}
}
for (auto x : ans)cout << x << endl;
return 0;
}
4. 判断二叉搜索树
题目链接:判断二叉搜索树
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
int n;
vector<int>v1;
vector<int>v2;
vector<int>v3;
tree create(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = x;
}
else
{
if (x < T->data)
T->left = create(T->left, x);
else T->right = create(T->right, x);
}
return T;
}
tree create2(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = x;
}
else
{
if (x < T->data)
T->right = create2(T->right, x);
else T->left = create2(T->left, x);
}
return T;
}
void pre(tree T)
{
if (!T)return;
v2.push_back(T->data);
pre(T->left);
pre(T->right);
}
void pre2(tree T)
{
if (!T)return;
v3.push_back(T->data);
pre2(T->left);
pre2(T->right);
}
void pos(tree T)
{
if (!T)return;
pos(T->left);
pos(T->right);
cout << T->data << ' ';
}
int main()
{
cin >> n;
tree T = nullptr;
tree T2 = nullptr;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
v1.push_back(x);
T = create(T, x);
T2 = create2(T2, x);
}
pre(T);
pre2(T2);
bool f = false;
bool s = false;
for (int i = 0; i < v1.size(); i++)
{
if (v1[i] != v2[i])
{
f = true;
break;
}
}
for (int i = 0; i < v1.size(); i++)
{
if (v1[i] != v3[i])
{
s = true;
break;
}
}
if (!f && s)
{
puts("YES");
pos(T);
}
else if (f && !s)
{
puts("YES");
pos(T2);
}
else if (!f && !s)
{
puts("YES");
pos(T);
}
else puts("NO");
return 0;
}
5. 完全二叉搜索树
题目链接:完全二叉搜索树 完全二叉树,所以可以用数组来存: 该结点为 u ,左孩子为 2 * u ,右孩子为 2 * u + 1 则这个数组1~n是全部填满的 二叉搜索树的中序遍历是从小到大的排序,所以先进行sort就是这棵树的中序遍历,再根据中序遍历存这棵树,将res数组枚举就是层序遍历
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
int in[N];
int res[N];
int cnt = 0;
void dfs(int u)
{
if (u * 2 <= n)dfs(u * 2);
res[u] = in[cnt++];
if (u * 2 + 1 <= n)dfs(u * 2 + 1);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> in[i];
sort(in, in + n);
dfs(1);
for (int i = 1; i <= n; i++)cout << res[i] << ' ';
return 0;
}
6. 再次树遍历
题目链接 :再次树遍历 对于每一个push操作可以看成先序遍历,pop可以看作先序遍历 根据两种遍历还原树并求出后续遍历
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
int a[N], b[N];
int c[N];
int n;
string op;
int x;
int cnt1, cnt2;
int k = 0;
vector<int>v;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
tree create(int len, int* c, int* b)
{
if (len <= 0)return nullptr;
tree T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = c[0];
int i = 0;
for (i = 0; i < len; i++)
if (T->data == b[i])
break;
T->left = create(i, c + 1, b);
T->right = create(len - i - 1, c + i + 1, b + i + 1);
return T;
}
void pos(tree T)
{
if (!T)return;
pos(T->left);
pos(T->right);
v.push_back(T->data);
}
int main()
{
cin >> n;
while (cin >> op)
{
if (op == "Push")
{
cin >> x;
a[cnt1++] = x;
c[k++] = x;
}
else
b[cnt2++] = a[--cnt1];
}
tree T = nullptr;
T = create(k, c, b);
pos(T);
for (int i = 0; i < v.size(); i++)
{
cout << v[i];
if (i < v.size() - 1)cout << ' ';
}
return 0;
}
7. 构建二叉搜索树
题目链接:构建二叉搜索树 二叉搜索树,中序遍历是从小到大的排序,先将其进行排序,根据其输入再用中序遍历将其还原,最后进行层序遍历
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n;
struct node
{
int l, r;
int data;
}tr[N];
vector<int>v;
int cnt;
void dfs(int u)
{
if (u == -1)return;
if (~tr[u].l)dfs(tr[u].l);
tr[u].data = v[cnt++];
if (~tr[u].r)dfs(tr[u].r);
}
void bfs(int u)
{
queue<int>q;
q.push(u);
while (q.size())
{
auto t = q.front();
q.pop();
cout << tr[t].data << ' ';
if (~tr[t].l)q.push(tr[t].l);
if (~tr[t].r)q.push(tr[t].r);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> tr[i].l >> tr[i].r;
v.resize(n);
for (auto& x : v)cin >> x;
sort(v.begin(), v.end());
dfs(0);
bfs(0);
return 0;
}
8. 反转二叉树
题目链接:反转二叉树 反向建树,哈希标记找根节点,中序和层序遍历输出
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
struct node
{
int data;
int l, r;
}tr[N];
int n;
unordered_map<int, bool>mp;
void dfs(int u)
{
if (~tr[u].l)dfs(tr[u].l);
cout << tr[u].data << ' ';
if (~tr[u].r)dfs(tr[u].r);
}
void bfs(int u)
{
queue<int>q;
q.push(u);
while (q.size())
{
auto t = q.front();
q.pop();
cout << tr[t].data << ' ';
if (~tr[t].l)q.push(tr[t].l);
if (~tr[t].r)q.push(tr[t].r);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
char a, b;
cin >> a >> b;
if (b != '-')
{
mp[b - '0'] = true;
tr[i].l = b - '0';
}
else tr[i].l = -1;
if (a != '-')
{
mp[a - '0'] = true;
tr[i].r = a - '0';
}
else tr[i].r = -1;
tr[i].data = i;
}
int root = -1;
for (int i = 0; i < n; i++)
{
if (!mp.count(i))
{
root = i;
break;
}
}
bfs(root);
cout << endl;
dfs(root);
return 0;
}
9. 完全二叉树
看到完全二叉树自然想到2 * u, 2 * u+1 这样可以判断其是否是一个完全二叉树。
#include <bits/stdc++.h>
using namespace std;
const int N = 55;
struct node
{
int l, r;
int data;
}tr[N];
unordered_map<int, bool>mp;
int n;
int maxv;
int ud;
void dfs(int u, int k)
{
if(u==-1)return;
if (k > maxv)
{
maxv = k;
ud = u;
}
dfs(tr[u].l, 2 * k);
dfs(tr[u].r, 2 * k + 1);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
string a, b;
cin >> a >> b;
if (a != "-")
{
int t = 0;
for (int i = 0; i < a.size(); i++)
t = t * 10 + a[i] - '0';
tr[i].l = t;
mp[t] = true;
}
else tr[i].l = -1;
if (b != "-")
{
int t = 0;
for (int i = 0; i < b.size(); i++)
t = t * 10 + b[i] - '0';
tr[i].r = t;
mp[t] = true;
}
else tr[i].r = -1;
tr[i].data = i;
}
int root = -1;
for (int i = 0; i < n; i++)
if (!mp.count(i))
{
root = i;
break;
}
dfs(root, 1);
if (maxv == n)cout << "YES " << ud << endl;
else cout << "NO " << root << endl;
return 0;
}
10. 二叉树最后两层结点的个数
题目链接:二叉树最后两层结点的个数 求树的深度的同时保存当前深度的结点个数
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
int n;
int cnt[N];
int h;
tree create(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = x;
}
else
{
if (x <= T->data)T->left = create(T->left, x);
else T->right = create(T->right, x);
}
return T;
}
void dfs(tree T, int depth)
{
if (!T)return;
cnt[depth]++;
h = max(h, depth);
if (T->left)dfs(T->left, depth + 1);
if (T->right)dfs(T->right, depth + 1);
}
int main()
{
cin >> n;
tree T = nullptr;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
T = create(T, x);
}
dfs(T, 1);
printf("%d + %d = %d", cnt[h], cnt[h - 1], cnt[h - 1] + cnt[h]);
return 0;
}
11. 前序遍历和后续遍历
题目链接:前序遍历和后序遍历 前序遍历和后序遍历无法确定一个二叉树,这题通过枚举左子树右子树的长度,判断这棵树是否合法,并将中序遍历存在字符串中
#include <bits/stdc++.h>
using namespace std;
const int N = 40;
int n;
int pre[N], pos[N];
int dfs(int len, int *pre, int *pos, string& in)
{
if (len <= 0)return 1;
if (pre[0] != pos[len - 1])return 0;
int cnt = 0;
for (int i = 0; i < len; i++)
{
string lin, rin;
int lcnt = dfs(i, pre + 1, pos, lin);
int rcnt = dfs(len - i - 1, pre + 1 + i, pos + i, rin);
cnt += lcnt * rcnt;
if (lcnt && rcnt)
in = lin + to_string(pre[0]) + ' ' + rin;
if (cnt > 1)break;
}
return cnt;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> pre[i];
for (int i = 0; i < n; i++)cin >> pos[i];
string in;
int cnt = dfs(n, pre, pos, in);
if (cnt > 1)puts("No");
else puts("Yes");
in.pop_back();
cout << in << endl;
return 0;
}
12. Z 字形遍历二叉树
题目链接:Z字形遍历二叉树 队列中的点为当前层的结点
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
int n;
int in[N], pos[N];
vector<int>v, res;
tree create(int len, int* in, int* pos)
{
if (len <= 0)return nullptr;
tree T = new node;
T->left = T->right = nullptr;
T->data = pos[len - 1];
int i = 0;
for (i = 0; i < len; i++)
if (T->data == in[i])
break;
T->left = create(i, in, pos);
T->right = create(len - i - 1, in + i + 1, pos + i);
return T;
}
void bfs(tree T)
{
queue<tree>q;
q.push(T);
int f=1;
while (q.size())
{
int s=q.size();
while (s--)
{
auto t = q.front();
q.pop();
v.push_back(t->data);
if(t->left)q.push(t->left);
if(t->right)q.push(t->right);
}
if (~f)reverse(v.begin(), v.end());
for (auto x : v)res.push_back(x);
f *= -1;
v.clear();
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> in[i];
for (int i = 0; i < n; i++)cin >> pos[i];
tree T = nullptr;
T = create(n, in, pos);
bfs(T);
for (auto x : res)cout << x << ' ';
return 0;
}
13. 后序遍历
题目链接:后序遍历建树 通过前序遍历和中序遍历建树,回溯时第一个数字即为后序遍历的第一个数字
#include <bits/stdc++.h>
using namespace std;
const int N=50010;
typedef struct node
{
int data;
node *left,*right;
}node,*tree;
int pre[N], in[N];
int n;
vector<int>v;
tree create(int len,int *pre,int *in)
{
if(len<=0)return nullptr;
tree T=new node;
T->left=T->right=nullptr;
T->data=pre[0];
int i=0;
for(i=0;i<len;i++)
if(T->data==in[i])
break;
T->left=create(i,pre+1,in);
T->right=create(len-i-1,pre+1+i,in+1+i);
v.push_back(T->data);
if(v.size()==1)
{
cout<<v[0];
exit(0);
}
return T;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>pre[i];
for(int i=0;i<n;i++)cin>>in[i];
tree T=nullptr;
T=create(n,pre,in);
return 0;
}
14. AVL树的根
题目链接:AVL树的根 记得每次要更新高度
#include <bits/stdc++.h>
using namespace std;
typedef struct node
{
int data;
node* left, * right;
int hight;
}node, * tree;
int n;
int get_hight(tree T)
{
if (!T)return 0;
else return T->hight;
}
tree L(tree T)
{
tree B = T->left;
T->left = B->right;
B->right = T;
T->hight = max(get_hight(T->left), get_hight(T->right)) + 1;
B->hight = max(get_hight(B->left), get_hight(T)) + 1;
return B;
}
tree R(tree T)
{
tree B = T->right;
T->right = B->left;
B->left = T;
T->hight = max(get_hight(T->left), get_hight(T->right)) + 1;
B->hight = max(get_hight(B->right), get_hight(T)) + 1;
return B;
}
tree LR(tree T)
{
T->left = R(T->left);
return L(T);
}
tree RL(tree T)
{
T->right = L(T->right);
return R(T);
}
tree create(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->right = T->right = nullptr;
T->hight = 0;
T->data = x;
}
else if (x < T->data)
{
T->left = create(T->left, x);
if (get_hight(T->left) - get_hight(T->right) == 2)
if (x < T->left->data)
T = L(T);
else T = LR(T);
}
else if (x > T->data)
{
T->right = create(T->right, x);
if (get_hight(T->left) - get_hight(T->right) == -2)
if (x > T->right->data)
T = R(T);
else T = RL(T);
}
T->hight = max(get_hight(T->left), get_hight(T->right)) + 1;
return T;
}
int main()
{
cin >> n;
tree T = nullptr;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
T = create(T, x);
}
cout << T->data << endl;
return 0;
}
15. 判断完全AVL树
题目链接:判断完全AVL树 判断是否为完全二叉树 如果该节点没有孩子,其层序遍历的之后的结点存在,且有孩子,则不是完全二叉树。或某结点没有左孩子只有有孩子也不是完全二叉树。
#include <bits/stdc++.h>
using namespace std;
typedef struct node
{
int data;
int height;
node* left, * right;
}node, * tree;
bool f = false;
int n;
int get_height(tree T)
{
if (!T)return 0;
return T->height;
}
void updateHeight(tree& T)
{
T->height = max(get_height(T->left), get_height(T->right)) + 1;
}
int getFactor(tree T)
{
return get_height(T->left) - get_height(T->right);
}
void L(tree& T)
{
tree B = T->right;
T->right = B->left;
B->left = T;
updateHeight(T);
updateHeight(B);
T = B;
}
void R(tree& T)
{
tree B = T->left;
T->left = B->right;
B->right = T;
updateHeight(T);
updateHeight(B);
T = B;
}
tree create(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = x;
T->height = 1;
}
else
{
if (x < T->data)
{
T->left = create(T->left, x);
updateHeight(T);
if (getFactor(T) == 2)
{
if (getFactor(T->left) == 1)
R(T);
else if (getFactor(T->left) == -1)
{
L(T->left);
R(T);
}
}
}
else
{
T->right = create(T->right, x);
updateHeight(T);
if (getFactor(T) == -2)
{
if (getFactor(T->right) == -1)
L(T);
else if (getFactor(T->right) == 1)
{
R(T->right);
L(T);
}
}
}
}
return T;
}
void bfs(tree T)
{
queue<tree>q;
q.push(T);
while (q.size())
{
auto t = q.front();
q.pop();
cout << t->data << ' ';
if (t->left == nullptr || t->right == nullptr)
if (q.front() && (q.front()->left || q.front()->right))f = true;
if (t->left == nullptr && t->right)f = true;
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
}
int main()
{
cin >> n;
tree T = nullptr;
for (int i = 0, x; i < n, cin >> x; i++)
T = create(T, x);
bfs(T);
cout << endl;
if (f)puts("NO");
else puts("YES");
return 0;
}
16. 判断红黑树
题目链接:判断红黑树
#include <bits/stdc++.h>
using namespace std;
vector<int>pre;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
int _, n;
tree create(tree T, int x)
{
if (!T)
{
T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = x;
}
else
{
if (abs(x) < abs(T->data))
T->left = create(T->left, x);
else T->right = create(T->right, x);
}
return T;
}
bool check(tree T)
{
if (!T)return true;
if (T->data < 0)
{
if (T->left && T->left->data < 0)return false;
if (T->right && T->right->data < 0)return false;
}
return check(T->left) && check(T->right);
}
int get_num(tree T)
{
if (!T)return 0;
int l = get_num(T->left);
int r = get_num(T->right);
if (T->data > 0)return max(l, r) + 1;
else return max(l, r);
}
bool check2(tree T)
{
if (!T)return true;
int l = get_num(T->left);
int r = get_num(T->right);
if (l != r)return false;
return check2(T->left) && check2(T->right);
}
void solve()
{
cin >> n;
pre.resize(n);
tree T = nullptr;
for (int i = 0; i < n; i++)
{
cin >> pre[i];
T = create(T, pre[i]);
}
if (T->data < 0 || !check(T) || !check2(T))puts("No");
else puts("Yes");
}
int main()
{
cin >> _;
while (_--)solve();
}
17. 等重路径
题目链接:等重路径 在叶子层时判断是否等重,是则保留结果
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int g[N][N];
int n, m, S;
vector<vector<int>>ans;
vector<int>path;
int w[N];
void dfs(int u, int s, vector<int>& path)
{
bool is_leaf = true;
for (int i = 0; i < n; i++)
if (g[u][i])
{
is_leaf = false;
break;
}
if (is_leaf)
{
if (s == S)
ans.push_back(path);
}
else if (!is_leaf)
{
for (int i = 0; i < n; i++)
{
if (g[u][i])
{
path.push_back(w[i]);
dfs(i, s + w[i], path);
path.pop_back();
}
}
}
}
int main()
{
cin >> n >> m >> S;
for (int i = 0; i < n; i++)cin >> w[i];
path.push_back(w[0]);
for (int i = 0; i < m; i++)
{
int id, k;
cin >> id >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
g[id][x] = 1;
}
}
dfs(0, w[0], path);
sort(ans.begin(), ans.end(), greater<vector<int>>());
for (auto x : ans)
{
for (int i = 0; i < x.size(); i++)cout << x[i] << ' ';
cout << endl;
}
return 0;
}
18. 最大的一代
题目链接:最大的一代 层序遍历求该层最多结点并保存 也可以深搜记录每个深度的结点数 bfs
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int g[N][N];
int n, m;
vector<int>res;
int cnt;
int cnt_r;
void bfs()
{
queue<int>q;
q.push(1);
while (q.size())
{
int s = q.size();
vector<int>v;
while (s--)
{
auto t = q.front();
q.pop();
v.push_back(t);
for (int i = 1; i <= n; i++)
if (g[t][i])q.push(i);
}
cnt++;
if (v.size() > res.size())
{
res.clear();
for (auto x : v)res.push_back(x);
cnt_r = cnt;
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int id, k;
cin >> id >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
g[id][x] = 1;
}
}
bfs();
cout << res.size() << ' ' << cnt_r;
return 0;
}
dfs
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int g[N][N];
int n, m;
int cnt[N];
int maxv;
void dfs(int u, int depth)
{
cnt[depth]++;
maxv = max(maxv, depth);
for (int i = 1; i <= n; i++)
if (g[u][i])
dfs(i, depth + 1);
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int id, k;
cin >> id >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
g[id][x] = 1;
}
}
dfs(1, 1);
int res = 0;
int d = 0;
for (int i = 1; i <= maxv; i++)
{
if (cnt[i] > res)
{
res = cnt[i];
d = i;
}
}
cout << res << ' ' << d << endl;
return 0;
}
19. 供应链总销售额
题目链接:供应链总销售额 深搜,在叶子结点处计算销售额
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int>v[N];
int n;
double p;
double r;
double w[N];
double sum;
void dfs(int u, int depth)
{
bool is_leaf = true;
for (int i = 0; i < v[u].size(); i++)
if (v[u][i])
{
is_leaf = false;
break;
}
if (is_leaf)sum += w[u] * p * pow(1 + r, depth);
else
for (int i = 0; i < v[u].size(); i++)
if (v[u][i])dfs(v[u][i], depth + 1);
}
int main()
{
cin >> n >> p >> r;
r /= 100;
for (int i = 0; i < n; i++)
{
int k;
cin >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
v[i].push_back(x);
}
if (!k)
{
int x;
cin >> x;
w[i] = x;
}
}
dfs(0, 0);
printf("%.1f", sum);
return 0;
}
20. 供应链的最高价格
题目链接:供应链的最高价格 记忆化搜索
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
double P, R;
int n;
int p[N], f[N];
int dfs(int u)
{
if (~f[u])return f[u];
if (p[u] == -1)return f[u] = 0;
return f[u] = dfs(p[u]) + 1;
}
int main()
{
cin >> n >> P >> R;
for (int i = 0; i < n; i++)cin >> p[i];
memset(f, -1, sizeof f);
int res = 0, cnt = 0;
for (int i = 0; i < n; i++)
{
if (dfs(i) > res)
{
res = dfs(i);
cnt = 1;
}
else if (dfs(i) == res)cnt++;
}
printf("%.2f %d\n", P * pow(1 + R / 100, res), cnt);
return 0;
}
21. 供应商的最低价格
题目链接:供应商的最低价格 深搜,求每层结点数量
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int>v[N];
int w[N];
int n;
double P, R;
int cnt[N];
void dfs(int u, int depth)
{
bool is_leaf = true;
if (v[u].size())is_leaf = false;
if (is_leaf)cnt[depth]++;
else
{
for (int i = 0; i < v[u].size(); i++)
dfs(v[u][i], depth + 1);
}
}
int main()
{
cin >> n >> P >> R;
R /= 100;
for (int i = 0; i < n; i++)
{
int k;
cin >> k;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
v[i].push_back(x);
}
}
dfs(0, 0);
int minv = 0x3f3f3f3f;
for (int i = 0; i < n; i++)
{
if (cnt[i] != 0)
{
minv = i;
break;
}
}
printf("%.4f %d", P * pow(1 + R, minv), cnt[minv]);
return 0;
}
22. 中缀表达式
题目链接: 中缀表达式 如果该节点不是根节点 则在该返回值的左右两边加上括号
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int n;
struct node
{
int l, r;
string data;
}tr[N];
unordered_map<int, bool>mp;
bool is_leaf[N];
string dfs(int u)
{
string left, right;
if (~tr[u].l)
{
left = dfs(tr[u].l);
if (!is_leaf[tr[u].l])left = "(" + left + ")";
}
if (~tr[u].r)
{
right = dfs(tr[u].r);
if (!is_leaf[tr[u].r])right = "(" + right + ")";
}
return left + tr[u].data + right;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> tr[i].data >> tr[i].l >> tr[i].r;
if (~tr[i].l)mp[tr[i].l] = true;
if (~tr[i].r)mp[tr[i].r] = true;
if (tr[i].r == -1 && tr[i].l == -1)is_leaf[i] = true;
}
int root = -1;
for(int i=1;i<=n;i++)
if (!mp[i])
{
root = i;
break;
}
cout << dfs(root) << endl;
return 0;
}
23. 堆路径
题目链接:堆路径
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
int v[N];
vector<int>path;
bool is_great = true, is_min = true;
void dfs(int u)
{
path.push_back(v[u]);
if (u * 2 > n)
{
cout << path[0] << ' ';
for (int i = 1; i < path.size(); i++)
{
cout << path[i] << ' ';
if (path[i - 1] > path[i])is_min = false;
if (path[i - 1] < path[i])is_great = false;
}
cout << endl;
}
if (u * 2 + 1 <= n)dfs(u * 2 + 1);
if (u * 2 <= n)dfs(u * 2);
path.pop_back();
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)cin >> v[i];
dfs(1);
if (is_great)puts("Max Heap");
else if (is_min)puts("Min Heap");
else puts("Not Heap");
return 0;
}
24. 最近公共祖先
最近公共祖先 二叉搜索树特性: 父节点 > 左儿子,父节点 <= 右儿子 前序遍历特性:根->左->右的顺序遍历 从前序遍历中找到第一个符合二叉搜索树特性的结点为x,y的共同父节点 建立哈希表,检查当前节点是否是该树的结点
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, m;
int pre[N];
unordered_map<int, bool>mp;
int main()
{
cin >> m >> n;
for (int i = 0; i < n; i++)
{
cin >> pre[i];
mp[pre[i]] = true;
}
for (int i = 0; i < m; i++)
{
int x, y;
cin >> x >> y;
if (mp[x] && mp[y])
{
int fa;
for (int j = 0; j < n; j++)
{
if (pre[j] >= x && pre[j] <= y || pre[j] >= y && pre[j] <= x)
{
fa = pre[j];
break;
}
}
if (x == fa || y == fa) printf("%d is an ancestor of %d.\n", fa, fa != x ? x : y);
else printf("LCA of %d and %d is %d.\n", x, y, fa);
}
else
{
if(!mp[x]&&!mp[y])printf("ERROR: %d and %d are not found.\n", x, y);
else if(!mp[x])printf("ERROR: %d is not found.\n", x);
else if(!mp[y])printf("ERROR: %d is not found.\n", y);
}
}
return 0;
}
25. 二叉树的最近公共祖先
题目链接:二叉树的最近公共最先
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, m;
int pre[N], in[N];
unordered_set<int>S;
unordered_map<int, int>mp;
typedef struct node
{
int data;
node* left, * right;
}node, * tree;
tree create(int len, int* pre, int* in)
{
if (len <= 0)return nullptr;
tree T = (tree)malloc(sizeof(struct node));
T->left = T->right = nullptr;
T->data = pre[0];
int i = 0;
for (i = 0; i < len; i++)
if (T->data == in[i])
break;
T->left = create(i, pre + 1, in);
T->right = create(len - i - 1, pre + i + 1, in + i + 1);
return T;
}
tree find(tree T, int x, int y)
{
if (!T || T->data == x || T->data == y)return T;
tree l = find(T->left, x, y);
tree r = find(T->right, x, y);
return l && r ? T : l ? l : r;
}
int main()
{
cin >> m >> n;
for (int i = 0; i < n; i++)
{
cin >> in[i];
mp[in[i]] = i;
}
for (int i = 0; i < n; i++)cin >> pre[i];
for (int i = 0; i < n; i++)S.insert(pre[i]);
tree T = create(n, pre, in);
while (m--)
{
int x, y;
cin >> x >> y;
if (!S.count(x) || !S.count(y))
{
if (!S.count(x) && !S.count(y))printf("ERROR: %d and %d are not found.\n", x, y);
else if (!S.count(x))printf("ERROR: %d is not found.\n", x);
else printf("ERROR: %d is not found.\n", y);
continue;
}
tree lca = find(T, x, y);
if (lca->data != x && lca->data != y)printf("LCA of %d and %d is %d.\n", x, y, lca->data);
else if (lca->data == x)printf("%d is an ancestor of %d.\n", x, y);
else printf("%d is an ancestor of %d.\n", y, x);
}
return 0;
}
|