题目链接:二叉树、堆、树堆
A:
思路:二叉树插入+前序遍历
#include <iostream>
using namespace std;
const int maxn = 100100;
int a[maxn];
int k;
struct node
{
int val;
node* lch, * rch;
};
node* insert(node* p, int x)
{
if (p == NULL)
{
p = new node;
p->val = x;
p->lch = p->rch = NULL;
return p;
}
else
{
if (x < p->val) p->lch = insert(p->lch, x);
else p->rch = insert(p->rch, x);
return p;
}
}
void preorder(node* p)
{
if (p == NULL)
return;
a[++k] = p->val;
preorder(p->lch);
preorder(p->rch);
}
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
k = 0;
node* p = NULL;
for (int i = 1; i <= n; i++) { int tmp; scanf("%d", &tmp); p = insert(p, tmp); }
preorder(p);
for (int i = 1; i <= k; i++)
{
if (i == 1) printf("%d", a[i]);
else printf(" %d", a[i]);
}
printf("\n");
}
}
B:
思路:二叉树插入+查询 模拟精灵移动
#include <iostream>
#include <queue>
#include <string>
using namespace std;
struct node
{
int val;
node* lch, * rch;
};
node* insert(node* p, int x)
{
if (p == NULL)
{
p = new node;
p->val = x;
p->lch = NULL;
p->rch = NULL;
return p;
}
else
{
if (x < p->val) p->lch = insert(p->lch, x);
else p->rch = insert(p->rch, x);
return p;
}
}
void find(node* p, int x)
{
if (x == p->val) return;
else if (x < p->val) { cout << 'E'; return find(p->lch, x); }
else if (x >= p->val) {
cout << 'W'; return find(p->rch, x);
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
int tmp;
cin >> t;
while (t--)
{
node* p = NULL;
int n;
cin >> n;
while (n--)
{
cin >> tmp;
p = insert(p, tmp);
}
int q;
cin >> q;
while (q--)
{
cin >> tmp;
find(p, tmp);
cout << '\n';
}
}
}
C:
思路:优先队列
#include <iostream>
#include <queue>
#include <string>
using namespace std;
struct node
{
string name;
int para, prio, id;
}tmp;
bool operator < (const node& n1, const node& n2)
{
if (n1.prio == n2.prio) return n1.id > n2.id;
return n1.prio > n2.prio;
}
priority_queue <node> pq;
string s;
int main()
{
ios::sync_with_stdio(false);
int id = 0;
int para, prio;
while (cin >> s)
{
if (s[0] == 'G')
{
if (pq.empty()) cout << "EMPTY QUEUE!\n";
else
{
node t = pq.top();
pq.pop();
cout << t.name << " " << t.para << endl;
}
}
else
{
cin >> s >> para >> prio;
tmp.name = s;
tmp.para = para;
tmp.prio = prio;
tmp.id = ++id;
pq.push(tmp);
}
}
}
E:
思路:后面不再出现的最小的编号就是叶子节点,使用优先队列逐个弹出构建树,然后再进行前序遍历
#include <sstream>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
int f[55], ans[55];
vector <int> vec[55];
string s;
priority_queue<int, vector<int>, greater<int> > pq;
void dfs(int x)
{
printf("(");
printf("%d", x);
int m = vec[x].size();
sort(vec[x].begin(), vec[x].end());
for (int i = 0; i < m; i++)
{
printf(" ");
dfs(vec[x][i]);
}
printf(")");
vec[x].clear();
}
int main()
{
char c;
while (getline(cin, s))
{
memset(ans, 0, sizeof(ans));
while (pq.size()) pq.pop();
int n = 0;
stringstream ss(s);
for (; ss >> f[n]; n++)
ans[f[n]]++;
n--;
for (int i = 1; i <= n + 1; i++)
if (ans[i]==0) pq.push(i);
for (int i = 0; i <= n; i++)
{
int tmp = pq.top();
pq.pop();
vec[f[i]].push_back(tmp);
if (ans[f[i]] == 1) pq.push(f[i]);
ans[f[i]]--;
}
if (n != -1) dfs(f[n]);
else printf("(1)");//输入为0
printf("\n");
}
}
F:
思路:直接利用stl中set是红黑树实现的特性,从set的头部和尾部进行操作,单次操作复杂度O(logn)
#include <iostream>
#include <set>
using namespace std;
struct node
{
int id, val;
bool operator < (const node &n) const
{
return val < n.val;
}
};
set <node> st;
int main()
{
int op;
while (scanf("%d", &op) != EOF)
{
if (op == 0) break;
if (op == 1)
{
int id, val;
scanf("%d%d", &id, &val);
node tmp;
tmp.id = id;
tmp.val = val;
st.insert(tmp);
}
else if (op == 2)
{
if (st.empty()) { printf("0\n"); continue; }
set<node>::iterator it = --st.end();
printf("%d\n", it->id);
st.erase(it);
}
else if (op == 3)
{
if (st.empty()) { printf("0\n"); continue; }
set<node>::iterator it = st.begin();
printf("%d\n", it->id);
st.erase(it);
}
}
}
G:
思路:stl中crope 可代替可持续化
#include <iostream>
#include<ext/rope>
using namespace __gnu_cxx;
crope r, his[50050], tmp;
char s[250];
int main()
{
int n;
scanf("%d", &n);
int d = 0, cnt = 0;
while (n--)
{
int op;
scanf("%d", &op);
if (op == 1)
{
int p;
scanf("%d%s", &p, s);
p -= d;
r.insert(p, s);
his[++cnt] = r;
}
else if (op == 2)
{
int p, c;
scanf("%d%d", &p, &c);
p -= d;
c -= d;
r.erase(p - 1, c);
his[++cnt] = r;
}
else if (op == 3)
{
int v, p, c;
scanf("%d%d%d", &v, &p, &c);
p -= d; c -= d; v -= d;
tmp = his[v].substr(p - 1, c);
d += count(tmp.begin(), tmp.end(), 'c');
std::cout << tmp << std::endl;
}
}
}
H:
思路:树状数组lowbit,对当前的编号减去lowbit再+1得到最深的左孩子,最深的右孩子同理
#include <iostream>
#include <queue>
#include <string>
using namespace std;
#define ll long long
int main()
{
ios::sync_with_stdio(false);
ll n;
cin >> n;
while (n--)
{
ll m;
cin >> m;
ll s = m & (-m);
cout << m - s + 1 << " " << m + s - 1 << endl;
}
}
I:
思路:构建以字母为值的二叉树,实现插入功能,再进行前序遍历
#include <iostream>
#include <queue>
#include <string>
using namespace std;
#define ll long long
struct node
{
char c;
node* lch, * rch;
};
node* insert(node* p, char c)
{
if (p == NULL)
{
p = new node;
p->c = c;
p->lch = NULL;
p->rch = NULL;
return p;
}
else
{
if (c < p->c) p->lch = insert(p->lch, c);
else p->rch = insert(p->rch, c);
return p;
}
}
void preorder(node *p)
{
if (p == NULL) return;
cout << p->c;
preorder(p->lch);
preorder(p->rch);
}
string s;
string str;
int main()
{
ios::sync_with_stdio(false);
while (cin>>s)
{
if (s == "$")
{
node* p = NULL;
for (int i = str.size() - 1; i >= 0; i--)
{
p = insert(p, str[i]);
}
preorder(p);
printf("\n");
return 0;
}
if (s != "*")
{
for (int i = s.size() - 1; i >= 0; i--) str.push_back(s[i]);
}
else
{
node* p = NULL;
for (int i = str.size() - 1; i >= 0; i--)
{
p = insert(p, str[i]);
}
preorder(p);
printf("\n");
str.clear();
}
}
}