Problem A
第一题最笨的思路(by:LittleSec)
都规定输入的最大深度是5了,所以直接穷举深度为1-5的满二叉树前序->中序方案,主要就是下标转换:
eg:输入ABC对应的下标是012,输出是顺序变成102而已。
eg:高度为3的情况则构造下标数组:a[] = {2,1,3,0,5,4,6},假设输入的字符串存在str,那么输出就是
for(int i = 0; i < pow(2,n)-1; i++)
{
if(str[a[i]]=='#') continue;
else cout << str[a[i]];
}
5种情况而已,草稿纸上列举不用10分钟。
亲测能通过所有测试样例。(:逃
第一题稍微不那么笨但还是很笨的思路(by:六月雪Yuni)
只要知道如何从满二叉树的先序遍历推出原树就可以做。根据定义,满二叉树的某一棵子树的先序遍历是[根][左子树序列][右子树序列]的形式,而且左子树序列和右子树序列长度相同。那么先取出根,然后递归处理左子树和右子树就可以构造出原树。得到原树之后中序遍历乱搞就可以啦。
另外值得注意的是有一些原本可以得到300分的大佬因为读题失误,把#节点认为是不存在的节点,而忽略了#节点也可能作为父节点的情况,导致本题只能做到80分或90分。呜呼哀哉————读题果然也是重要的一环呢。
这个思路得到了AC(100pts)。
伪代码:
void ConstructTree(int l, int r){
root = s[l];
root.leftChild = s[l+1];
root.rightChild = s[l+1+(r-l)/2];
ConstructTree(l+1,l+(r-l)/2);
ConstructTree(l+(r-l)/2+1,r);
}
void Output(int root){
Output(root.leftChild);
print(root);
Output(root.rightChild);
}
Problem B
第二题菜鸡拿分经验贴(by:还是最笨的LittleSec
题中给定输入是s t,千万认为s一定比t小。当s比t大的话,也就是农夫在牛的后面,那么农夫每次都只能执行后退即-1操作,因此最短步数就是s-t步。亲测能通过4个测试样例(噗
第二题思路1 广度优先搜索(by:六月雪Yuni)
直接从点s开始BFS。用一个数组vis[]维护元素x是否被加入过队列,d[]记录扩展到元素x需要搜索几步。
每次取出队首元素fr时,测试fr+1是否在队中,不在则加入队列,并且更新d[fr+1]。对fr-1和fr*2同样这么做。
需要注意的是加入队列的元素不能是负数,因为0<=s,t<=100000,加入负数没有意义。fr*2也不能超过100000。
这个思路做到了AC(100pts)。
部分代码:
int BFS(int s, int t){
memset(d,0x3f,sizeof(d)); //这一步将d中所有元素初始化为一个“无限大”,即在题目语境里非常大的数
const int inf = 0x3f3f3f3f;
d[s] = 0;
queue Q;
while(!Q.empty())Q.pop();
Q.push(s);
while(!Q.empty()){
int fr = Q.front();
if(fr-1>=0 && d[fr-1]>=inf){
Q.push(fr-1);
d[fr-1] = d[fr] + 1;
}
if(d[fr+1]>=inf){
Q.push(fr+1);
d[fr+1] = d[fr] + 1;
}
if(fr*2<=100000 && d[fr*2]>=inf){
Q.push(fr*2);
d[fr*2] = d[fr] + 1;
}
Q.pop(fr);
}
return d[t];//因为我们知道本题一定有解,所以不判定是否存在。
}
第二题思路3 DP
听说有大佬用动态规划解了这题,待补充。
Problem C
第三题思路1 DP(by 笔试爆炸啦qaq)
我们令dp[i][j]为串s[1..i]和t[1..j]的最长公共子序列长度。例如,对s="abcde"和t="acefg",s[1..4]="abcd",t[1..3]="ace",所以dp[4][3]=2。(最长公共子序列是"ac")
这样,就有了以下的递推式:
s[i] == t[j] : dp[i][j] = max(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]+1).
s[i] != t[j] : dp[i][j] = max(dp[i-1][j], dp[i][j-1]).
初始条件 dp[0][0] = 0
时间复杂度O(L^2),L = max(s.length, t.length).
然后dp[s.length][t.length]就是串s和串t的公共子序列长度。将这个过程重复n次、取最大就可以求得题目的解。因为1<=n<=200,L<=2000,所以可以在时限内得到解。
这个思路得到了AC(100pts)。