2016.11.08解题报告

来源:互联网 发布:汽车模型设计软件catia 编辑:程序博客网 时间:2024/04/29 13:35

2016.11.08解题报告

Part.1线段(segment)

贪心,线段覆盖问题。。。

解题思路

1. 保险起见,当ai>bi时交换一下;

2. 将线段按照右端点从小到大排序(C++选手可以用结构体存左右端点,然后重载小于号,再用sort,打起来省事儿);

3. 从1到n-1扫瞄,运用贪心策略:如果碰到前一条线段的右端点比后一条的左端点大,撤掉后一条线段(更新其左右端点为前一条的);

4. k初值为n,每撤一条k--。

Part.2 绘制二叉树(binary)

参考网上的题解吧,蒟蒻无能为力……

Part.3 编码(encode)

一个比较绕的递归过程,但时间复杂度相当低——如果能搞出来公式直接就O(logn)了,也就是说最多跑9次就直接出结果。

解题思路

关键是找规律,然后递归。仔细研究一下还是能看出来的:

1. 对于所求的q,每次变化都会有不包含q的一半区间用不上,也就是说每一层递归有用的变换区间都缩成一半,依次递归下去,每次只保留含q的区间,直到区间内仅有一个q,此时的位置就是答案。因此这就是个二分的过程,时间复杂度为O(logn)。

2. 对于每次变换,相当于每个字符(实现上直接用顺序的数字就好)交换到关于中心点对称的位置。我们只需要关注q的行为即可。具体的变换公式如下:

int mid=(l+r)/2;

if (n%2==1)  //区间长度为奇数,得到的mid在正中间;

{

 q=mid*2-q;

    if(q>mid)   return phi(mid+1,r,n/2,q);

    else returnphi(l,mid,n/2+1,q);

}else    //区间长度为偶,得到的mid是中间偏左的那一个;

{

    q=mid*2-q+1;

    if(q>mid) return phi(mid+1,r,n/2,q);

    else returnphi(l,mid,n/2,q);

}

Part.4 偷懒的小X(lazy)

原以为是建一个小根堆然后顺序弹出就好,每一层拣大的先弹出,结果华丽丽地WA了……

题意是在保证这棵满二叉树每个节点权值都比两个子节点小的条件下(其实就是满足小根堆的性质),使较大数尽可能靠前输出,所以尽量把大数集中到一边,小数集中到另一边,每一层先从大数里挑一半,再从小数里挑另一半。

解题思路

1. 从小到大排序;

3. 递归建小根堆:

每次把区间内的第一个数加入输出序列(先开一个数组)中,然后将后面的从中间分成两块,分别代表右子树、左子树,左大右小,同时把左右子树的编号赋给右、左半区间的第一个数。

排完序:12 3 4 5 6 7

建树——左大右小:

        1

       / \

     /     \

   5       2

  / \       / \

 7  6   4   3

0 0
原创粉丝点击