-
Archives
- January 2012
- December 2011
- August 2011
- July 2011
- June 2011
- April 2011
- March 2011
- February 2011
- January 2011
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
-
Meta
Monthly Archives: March 2010
POJ 3044 —— City Skyline
看了半天才知道这个题目的意思,说的是给定一些建筑的轮廓,问为了构成这些轮廓,至少需要多少建筑物?建筑外形都是矩形的,不可能存在空中楼阁。 从底部往上每出现一个新的高度则可能的建筑数量加 1。
Posted in POJ
Leave a comment
POJ 2886 —— Who Gets the Most Candies?
N 个小孩围成一圈,他们被顺时针编号为 1 到 N。每个小孩手中有一个卡片,上面有一个非 0 的数字,游戏从第 K 个小孩开始,他告诉其他小孩他卡片上的数字并离开这个圈,他卡片上的数字 A 表明了下一个离开的小孩,如果 A 是大于 0 的,则下个离开的是左手边第 A 个,如果是小于 0 的,则是右手边的第 -A 个小孩。游戏将直到所有小孩都离开,在游戏中,第 p 个离开的小孩将得到 F(p) 个糖果,F(p) 是 p 的约数的个数,问谁将得到最多的糖果。输出最幸运的小孩的名字和他可以得到的糖果。 首先求出 N 以内最大的反素数,它的因子的个数就是可以得到的糖果数,再根据反素数推出离开者的编号。
反素数
对于任何正整数 x,其约数的个数记做 g(x)。例如 g(1) = 1, g(6) = 4。如果某个正整数 x 满足:对于任意 i (0 < i < x),都有 g(i) < g(x),则称 x 为反素数。现在给一个 N,求出不超过 N 的最大的反素数。比如:输入1000,输出 840。 思维过程: 求约数的个数 756 = 2^2*3^3*7^1 (2+1)*(3+1)*(1+1) = 24 基于上述结论,给出算法:按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子。 为了剪枝: 性质一:一个反素数的质因子必然是从 2 开始连续的质数. 因为最多只需要 … Continue reading
POJ 2352 —— Stars
屏幕上很多星星,告知每个星星的坐标,每个星星的层次定义为不高于它并且不在其右边的星星数目,输入 N 个星星的坐标,求每个星星的层次。 不停搜索左子树即可。
Posted in POJ
Leave a comment
POJ 2828 —— Buy Tickets
卖票插队问题,有 N 个插队行为,告知每次要插到第 i 个位置上,问最后它们的顺序是什么。 建立线段树,每个人最终会被分配在一个叶节点上,从最后一个往第一个开始做插入操作,如果位置被占领,则仿照树的遍历将其放置到另外一个空位置。 参考: http://blog.csdn.net/logic_nut/archive/2009/08/30/4498825.aspx
POJ 3225 —— Help with Intervals
定义集合的几种操作,包括并、交等,问最终剩下的集合。 这个题目算是线段树比较经典的题目,可以加深对线段树的理解。对于每个节点,必须添加额外的字段。这是线段树的关键。 还有人给起名叫区间树: 区间树和线段数有一定程度的相似: 每个节点都表示一个区间。叶节点都表示单位区间。根节点表示整个全集的区间。 非叶节点的区间都平分成左、右两个子节点。 因此,整棵树是平衡二叉树。 但是区间树和线段树也有完全不同的地方: 区间树的节点上存放的变量及其含义与线段树不同。线段数一般是用来求和的,它的每个节点上存放了该区间内全部数组元素的和。而区间树的节点保存的则是布尔数组在该区间上的覆盖情况:全 1、全 0 或者是未知(需要进一步考查子节点)。 对线段树的每次操作都是针对一个叶节点。在一次操作过程中,只需要牵涉到一条从根到叶的路径,因此其时间复杂度为 O(lg N)。 而对于区间树,每次操作针对的是一个区间,可能会牵涉到多个分枝,但是它的时间复杂度也是 O(lg N)。 强烈推荐此题。 http://imlazy.ycool.com/post.1990834.html
POJ 3667 —— Hotel
有 N 个房间,有订房和退房操作,订房要求的是选择连续的几个房间,每次订房都是从编号最小的开始,问每次订房操作是否都可以满足。 这个也是线段树,但是节点信息需要进一步丰富。每个节点需要保存几点:当前左子节点最大连续空闲房间、右子节点最大空闲房间数,左右连续空闲房间数。
POJ 2528 —— Mayor’s posters
参考:http://blog.csdn.net/logic_nut/archive/2009/08/30/4497181.aspx 市长竞选,每个市长都往墙上贴海报,海报之间彼此可以覆盖,给出粘贴顺序和每个海报的起点和长度,问最后哪些海报是可见的。 这个题目和木棍涂色类似,但不同的是区间范围太大,你是不可能对 0 到 10000000 的区间来建线段树的。其实更值得关注的是每个海报跨度的地点和终点。将每张海报的起点和终点放到一个数组里,排序之后成为一个新数组 N,假设一张海报的起点和终点为 i 和 j,只要更新 i 和 j 在数组 N 之间的元素就和涂色问题一样处理了。。
POJ 3468 —— A Simple Problem with Integers
这个题目和前面的题目几乎一样,唯一不同的就是 32 位整数可能不够用,得用 64 位的。
HDU 1394 —— Minimum Inversion Number
这个是求逆序对的问题,基本的算法是 O(N^2) 复杂度。但利用线段树,可以缩短到 O(NlogN)。 http://hi.baidu.com/perfectcai_/blog/item/2a58300bc04e4f3ce924889a.html
HDU 1166 —— 敌兵布阵
给定一个序列,然后有很多操作,包括给下表为 i 与 j 之间的元素每个加上一个值,给下标为的 i 元素减掉一个值,查询第 i 到第 j 个下标之前元素的总和等等。 这也是一个典型的线段树问题。依据线段长度建树,每次增加或者减掉一个值的时候更新从根向下的节点。类似的问题包括 HDU 1754。 对于这种要多次查询的问题,qsort 肯定不是最佳方案。 线段树的关键在于每个节点的含义,其中可以加上你自己需要的东西。
POJ 2104 —— K-th Number
两种最常见的解法是所谓的线段树和树状数组。 为每个节点增加 2 个字段,一个表示该节点存放的序列的个数,另一个表示该节点存储的有序的序列,这会导致较大的空间需求。 尽管在整个序列看来是寻找第 k 大的元素,但是在树中,随着搜索的逐步下移,最终会归结为某个节点中所存放序列的折半查找。
ZOJ 1610 —— Count the Colors
对一根长度为 [0, 8000] 的木棍涂色,后涂的颜色将覆盖先前的颜色,问最后能看到哪些颜色,并问能看到多少段。 此题被认为是一个经典的线段树问题。