Greater New York 2005
match date:Friday, March 3, 2006
report date:Wednesday, March 15, 2006
Preface:
3月3日,上大冬季学期的考试在即,我却无心复习,继续迷茫在ACM/ICPC阵营。3日我试着做了一次SCU举办的比赛,题目是来自Greater New York 2005的,题目难度偏低吧,中等题目比较多。
在比赛中我做了四道题目,其中还和室友下了盘棋,嘿嘿,心情满休闲的嘛。在某牛牛BLOG里看到牛牛称这套题是水题,但我想学习要有鼓励,就用这套水题来鼓励鼓励我的自信吧。
Contents
Preface:
Contents:
Problem A: 01000001
Problem B: The Bank of Kalii
Problem C: The Cubic End
Problem D: Kindergarten Graduation
Problem E: brainf*ck
Problem F: Stacking Cylinders
Problem G: No Fold'em Hold'em
Problem H: Model Rocket Height
Problem I: Sequence Sum Possibilities
Links:
Problem A - 01000001:
二进制的加法,直接用JAVA大数做的。用C++也不会有很大难度。
Problem B – The Bank of Kalii:
第二题是有点累人的模拟题,题目是老掉牙的计算日期,只是这次不用计算具体某年某月的某日是星期几,而是问相邻两日之间的距离。
具体做法是对几个特殊的日子进行处理,而一般的日子直接算就行了,步骤如下:
先设默认天数8天,表示超过范围
月份相同,直接用两个日子相减
有一个是12,且另一个是1,则特别处理下
若两个月相差1,也特别处理下(注意此处要小心2月情况)
判断相差的天数,小于等于7、等于0、大于7,以及大小关系,给出结果
Problem C - The Cubic End:
这是一道还算有挑战性的题目,是比赛时做的最后一道,要推公式花了点力气,而解决防止溢出又花了点心思。
思路是带有一点递归色彩的,先解决sample的问题 947 的三次方以123结尾。因为有三次方,所以先写好这个公式(a+b)3=a3+3a2b+3ab2+b3 。947 = ( 900 + 47 ),所以9473=(900+47)3=9003+3*9002*47+3*900*472+473,可以看出四个项的前两个可以舍去,因为不会影响到结果的后三位。所以3*900*47^2只影响123的1,而47决定23,然后对47的三次进行分解( 40 + 7 ),就有3*40*7*7影响2,7决定3,这样就可以想到递推的方法了。
step1. 7*7*7 % 10 = 3
step2. 3*4*7*7%10 + 7*7*7 /10 % 10 = 2
step3. 3*9*7*7%10 + 47*47*47 /100 %10 = 1
以上是已知一个数,求其三次方的尾三位的解法,而如果要反过来求,其实也是用这种思路,从个位数开始对于每一个数i进行0-9的枚举,然后看相应尾数对上了就可以了。
另一个问题是在式中已经去掉了两个很大的项,但是简化后还是留了一个大项——b^3。对于十位数,当求到第十位时,其前面9位数的三次方必定超过表示范围,解决方法其实也很简单,因为我们要的只是对某一个有影响的位数,所以在进行三次方时,时时对计算结果取余,保留有影响的位就行了。
经过不停递推,最终就可以把这个数给推出来了。
Problem D - Kindergarten Graduation:
一道搜索题,原本用了一次DFS,结果和预料一样,超时了。然后写了个BFS,也是超(虽然是水题一套,不过也不会水到用简单的搜索就能过的)。其实只要注意以下几条剪支就行了:
B只能向左走,G只能向右走
左侧的B除了头位置,其他位置不能连续出现,比如BBB_**可以,GBB_**不可,因为这样左边的G在满足1的情况下会无法跳出来。
同2,右侧的G除了结尾,其他位置不能连续出现。保证右边B可以跳向左边。
这样,基本上就可以过了,只要保证不重复搜索(最基本的),应该没问题了。
Problem E - brainf*ck:
有郁闷了很长时间的,虽然看上去是简单模拟题,但是用JAVA不知道为什么老是TLE,而用C++就可以以相同的思路通过。
实际上也就是很简单的模拟题,我的处理是先读入所有的数据,在读入的同时判断其括号是否匹配及消除非操作符号和注释。
然后模拟执行一遍就行了,要对括号嵌套做一下处理,即准备个栈。对于0的时候跳出循环也要记住判别。
Problem F - Stacking Cylinders:
比赛时没去做这道题目,我是比赛后回来补的。原本这道题是在以前就已经出过的,但不知为什么,一样的题目这次又被拿了过来。详见PKU2194 。
题目是要求将球堆起来之后最高点的球的坐标,用尝试就能知道n个球可以堆n-1个球,然后n-1堆n-2,以此类推,最后就有一个球在最高处。这样用递推的方法就能求出最顶端的球的坐标了。大的思路就是这样,然后就是解决每个递推要用到的公式了。
把已知两个球求他们能顶的那个球的坐标,可以抽象为已知两个点,求第三个点,而这第三个点可以看作是等腰三角形的顶点,也可以认为是两个半径1的圆的交点,于是就有了两套方程:
由三角形的面积公式可以得 (a,b,c 为三边长,其中两条等于2为题目中已知的 )
于是就有了方程组的第一个方程 ( AB x AX )=2*area ,要注意的是这里叉乘的顺序不能随便变,因为第三点的坐标有上和下两种情况,区别在于一个叉乘所得为负area而另一个为正,所以这里要预先分析好取何种叉乘顺序。
再由距离的公式(也就是两圆求交)可以得出
( x - Ax )2 + ( y - Ay )2 = ( x - Bx )2 + ( y - By )2
消去一些二次项,就又有了方程组的第二个方程。将两方程联列求一下,就能解得X的坐标。
既然有了每个递推单元的公式,求解此题就没什么难度了。
Problem G - No Fold'em Hold'em:
巨恶心的一道题目,去网上查了梭哈规则又写了7K多的代码,结果WA了五次,在找到官方数据后才发觉其中中西方游戏规则的不同处有N多,才导致程序输出的结果与标准结果相差甚远。
我觉得这题没什么实际意义,对提高自身水平没啥帮助,所以这题最终还是选择放弃。
Problem H - Model Rocket Height:
这题是一道几何题,但题意太难懂,专业词汇太多,所以没做。
Problem I - Sequence Sum Possibilities:
需要推会儿公式的题目,用到的是连续数的和等于( as + ae )( ae - as +1 )/2 。这里就想到了将2倍的SUM做分解为两个因子,只要能找到as和ae满足( as + ae )为其中一个,( ae - as + 1)为另一个就可以了。
其实是解一组一元一次方程组,而且系数只有1和-1:
as + ae =s1
ae - as +1 =s2
相加一下,再减一下就可以求得as和ae了。但作为判定,先求出s1+s2-1 ,相当于2ae,先判断奇偶性,奇数则忽略掉,偶数则计数+1。再右移1求得ae,对s1-ae判断是否为正数且小于ae就可以得到一个解了,计数+1。
Links:
My Blog:
http://blog.csdn.net/ray58750034/
SCU Contest:
http://acm.scu.edu.cn/soj/contest/contest.action?cid=91
PKU 2194:
http://acm.pku.edu.cn/JudgeOnline/showproblem?problem_id=2194