8.8 美团笔试
总共五道题,4+1的形式。
第一题,要特判等于0的情况,否则是91%
第二题,忘掉了。
第三题,对于a[i],找到之前小于它的最大的数,可以维护一个set,每次处理完当前a[i],就插入到set中。对于处理,可以直接利用set的lower_bound(val),然后根据迭代器减1判断情况。
第四题,任选x修改为y,使得序列前一半与后一半相同,可以处理出不同的 pair{ a[i] , a[i+n/2] },然后默认first为较小值,去一下重 ( 相同的对计算一次贡献 ),然后建立无向图。优先从入度小的点出发DFS,每走一步就是一个花费,图遍历完就得答案。
第五题,对换左右子树,这个可以直接用数组表示存二叉树,点值对应题目要求的点序号,下标0开始,初始时左右儿子分别为2*x+1,2*x+2,然后根据修改,分别修改Lchild和Rchild的指向。第五题代码还没删掉,如下。
#include<bits/stdc++.h> using namespace std; int a[100020]; typedef pair<int,int> pii; int n,m,k; int loc[100020]; struct node{ int val; int L,R; }p[10000]; struct pre{ int L,R; }has[10000]; void solve(int x) { if(x>=n) return; loc[p[x].val]=x; p[x].L=p[x].R=0; int cur=p[x].val; int Lval=has[cur].L; int Rval=has[cur].R; if(Lval) { p[x].L=2*x+1; p[2*x+1].val=Lval; solve(2*x+1); } if(Rval) { p[x].R=2*x+2; p[2*x+2].val=Rval; solve(2*x+2); } } void print(int x) { if(p[x].L) print(p[x].L); cout<<p[x].val<<" "; if(p[x].R) print(p[x].R); } int main() { cin>>n>>m>>k; p[0].val=k; for(int i=1;i<=n;i++) { cin>>has[i].L>>has[i].R; } solve(0); for(int i=1;i<=m;i++) { int x; cin>>x; int id=loc[x]; swap(p[id].L,p[id].R); } print(0); }