就我自己的理解来分析一下”团体程序设计天梯赛“
天梯赛的规则是在3个小时内完成尽可能多的题,根据得分进行排名。
题目分为三个等级,第一个等级8道题共100分,考的是手速;第二个等级4道题共100分,除了考手速还考数据结构;第三个等级3道题共90分,再加一个算法。
感觉这三个等级阶段很有味道,因为听某大佬说过,算法的根基是数据结构。
这三个阶段的码量,大致就是第一阶段<30行,第二阶段普遍50多行,第三阶段普遍100多行。
下面对第二阶段(数据结构)做一个自己的分析。
第二阶段的核心是围绕着数据结构,也有坑点。
L2
栈:
1.dfs
void dfs(int u){
dvec[cd].push_back(u);
for(int i=0;i<n;i++){
if(st[i]==0&&a[u][i]==1){
st[i]=1;
dfs(i);
st[i]=0;
}
}
}
2.表达式转换
中缀转后缀
计算前缀
计算中缀
计算后缀
3.多栈互相插入,用STL
queue<int>q;
int n;
vector<int>bx;
int m;
vector<int>res[N];
int k,cnt;
队列:
bfs
vector<int>bvec[N];
int cb;
void bfs(int start){
queue<int>q;
q.push(start);
while(q.size()){
int u=q.front();
q.pop();
if(st[u]==1) continue;
st[u]=1;
for(int i=0;i<n;i++){
if(a[u][i]==1&&st[u]==1){
bvec[cb].push_back(u);
q.push(i);
}
}
}
}
链表:
用到链表的时候,也就是动态增加元素,防止爆空间,vector也可以做到
vector<T> vec[N];
实在不行的话,模拟链表
struct node{
int x,ne;
}nodes[N];
int n;
树:
int e[N],ne[M],h[M],idx;
void add(int u,int v){
e[idx]=v;ne[idx]=h[u];h[u]=idx++;
}
int idx;
void InorderSearch(int root){
if(root>n)
return ;
InorderSearch(root*2);
T[root]=data[index++];
InorderSearch(root*2+1);
}
struct node{
int val,lc,rc;
}tr[N];
int idx;
bool st[N];
4.通过中序遍历和后序遍历建树;然后前序遍历树
并查集:
int fa[N];
int find(int u){
return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
}
图:
dijkstra
spfa
floyd
kruskal
坑点
-
冰岛人
题意模糊。所谓“五代以内无公共祖先”是指两人的公共祖先(如果存在的话)必须比任何一方的曾祖父辈分高。 先查出一个人的五代以内公共祖先,然后再查出另一个人的公共祖先和第一个人比对,死活不能得满分。 坑点是一个人是另一个人的五代以上的祖宗,这样的话两人的公共祖先就是辈分高的那个人,出题人的脑洞真的大。
-
表达式转换
样例毒瘤。一个连续的字符串转换成表达式,有小数就不用说了,负数前面有负号也没什么问题,但是正数前面有正号是不是太离谱了点
- 二叉搜索树的2层结点统计
题意模糊。将一系列数字按给定顺序插入一棵初始为空的二叉搜索树,你的任务是统计结果树中最下面 2 层的结点数。
一种理解是统计从最下面叶节点开始2层的节点总数,还有一种理解是找到整棵树最下面一层统计这一层和上一层的节点总数。
L3
树状数组/线段树
最近公共祖先/虚拟原点/反图