天天看点

TopCoder SRM301 DIV1 Report

TopCoder SRM301 DIV1 Report

match date:Tuesday, May 9, 2006

report date:Thursday, May 11, 2006

Preface:

好久没做TOPCODER了,主要是因为SRM的时间都不好,大都在我有课或有事的时候,这次有机会做一次感觉满提神的,特别是这次有幸和Petr在一组!

总共是做了两道,都是花了很长时间才提交的。第一道被Petr给Challenge了,因为题意没审清,所以用Test数据就能Challenge掉。第二题花了好长时间改摸板,准备不充分呐。刚做完coding就掉线了,没能进入Challenge,所以也就没能再多拿什么分。

Problem 250 - IndicatorMotionReverse :

简单的模拟题,只是要注意一些小细节的问题。模拟好各种变换,得到一个包含所有变化的String a,再对重复的部分转变为 “指令 次数” 的形式,小心处理大于99次的指令,得到String b。然后截取目标b的前99个,若b超过99,则截取97个并加“...”。

Problem 450 – EscapingJail :

第二题题意满搞的,不过理清思路后就知道,该问题本质上就是求图的直径。所谓图的直径就是最长的最短路径,也就是在所有的最短路径中最长的那一条。

看穿了题目花哨的介绍后,就可以想到,用Floyd算法求出最短路径矩阵,再取最大值就行了。只是要小心处理两点之间无边的情况,我是设其为Integer.MAX_VALUE。

取最长值只要两个循环遍历最短路径矩阵,记下最长的两点就行了。

Problem 1000 - ContextFreeGrammars :

最后一题果然是难题,一共就7个人通过了。其考点应该是文法和动态规划方面的内容,对于不熟悉文法中一些技巧的人来将要过此题相当困难。

记得在编译原理课上层学过一些语法的表示(具体也不记得了),这题讨论的就是上下文无关文法(Context Free Grammar),CFG简单得说就是由 非终结符F、终结符T 组成,并标注起始的非终结符S及一系列规则R,关系是形如 F ::= F | FT | T ,对于无关文法,它要求左边只能有一个F。

对于此题,题目中已经用一种树型结构的演示给出了求解的基本思路, 反应快的应该马上就可以想到用dp或递归的方法来计算。如果不对题目的输入进行处理的话,那么得到的将是一个有向带环图,为了方便我们的计算,如果熟悉Chomsky范式(Chomsky normal form) 的话,就可以将CFG转化成CNF,而得到的将是一个形如二叉树的语法结构,有了这个结构对于解决该任务无疑是个法宝。CNF范式保证每条规则为 F ::= FF 、F ::= T或 S::=ε 。下面介绍转化方法:

为了使程序更加流畅,考虑 F::= TT,以A::=ab为例,他的CNF形式是

A::=BC B::= a C::=b

对于二叉树结构而言,A到a只有一条路,A到b也只有一条,其中多余的是B和C,所以我们可以投巧地放松CNF的规定,也就是允许 F::= FT、F::=TT、F::=TF三种形式。

宽松的CNF规定后,发现,只要保证所有的规则右端都小于3个就行了,即

对于右端为1的直接保留,否则

    设置左端符号L

    自左向右扫描{

        增加新规则 L ::=(当前符号)(新建符号T);

            设置 L = T;

            }

    调整最后两个规则

这样就可以得到一个转换后的满足CNF的规则了。留意,如果右端只有一个符号,F::=F是没有意义的,无关文法中也不会出现,而F::=T需要特别标注,为了和右端两个符号保持一至,用一个特殊符号表示它的第二个符号,如果用int的话可以用-1。

接着要准备dp过程了,我们维护一个三维的数组mem[i][j][k],表示从待查询单词的第i个位置开始到第j个位置,如果用符号k表示的话可以组合的概率。

不难理解,对于规则 A ::= BC可以有下式:

mem [i][j][A]=Sumk=1...j-i ( mem [i][i+k][B] * mem[i+k][j][C] )

因为前面用-1表示了右端只有一个符号的规则,所以这里遇到-1要跳过。

最后是确定初始化条件,然后只要照式子打dp程序就行了。由于该二叉树只有T才能做叶子结点,即对待查单词的每个字符c(位置为i)有 mem[i][i+1][c]=1。

再因为对于右端只有一个符号的规则没有在DP方程中处理,也不便于在该DP方程中处理,所以也要做预处理(该类规则一定比其他规则更接近叶子结点,所以要预先解决)。即对每个规则 F ::= T ,有 mem[indexOf(T)][indexOf(T)+1][F]++ ,indexOf(T) 返回T在待查词中的位置。

Links:

My statistic:

http://www.topcoder.com/stat?c=coder_room_stats&rd=9822&cr=20862220

SRM 301 - Problem Set & Analysis:

http://www.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm301

Graph Diameter :

http://mathworld.wolfram.com/GraphDiameter.html

Chomsky normal form :

          http://en.wikipedia.org/wiki/CYK_algorithm