Posts Tagged “solution”


ZOJ Monthly, December 2010
A ZOJ3446 Doraemon’s Battle 13.84% (54/390)
B ZOJ3447 Doraemon’s Number Game 29.66% (35/118)
C ZOJ3448 Doraemon’s Number Game II 0.00% (0/4)
D ZOJ3449 Doraemon’s Number Game III 18.77% (40/213)
E ZOJ3450 Doraemon’s Railgun 11.28% (22/195)
F ZOJ3451 Doraemon’s Shooting Practice 8.33% (2/24)
G ZOJ3452 Doraemon’s Stone Game 33.89% (20/59)
H ZOJ3453 Doraemon’s Sweet Bullet 25.00% (5/20)
I ZOJ3454 Nobita’s Letter 36.36% (8/22)
J ZOJ3455 Shizuka’s Letter 27.95% (26/93)
K ZOJ3456 Traveler Nobita 7.50% (3/40)

ZOJ3446. Doraemon’s Battle

downloadsource code (ZOJ3446.cpp) [search, bfs]

Doraemon初始有lh的血量和0的技能值,有n个敌人,他每回合有4种选择:

  • 消灭一个敌人并增加一个技能值;
  • 回复lh/5血量;
  • 用尽现有技能值s,打掉Ds个敌人;
  • 不动。

Doraemon回合之后,若剩下m个敌人,则其血量减少m,技能值增加m%3。Doraemon的血量若小于等于0,就挂了。问最少多少回合消灭所有敌人。

不动这个选择显然是没有好处的。只要从初始状态出发,用[h][s][n]标记走过状态,bfs就可以了。注意D数组不一定是递增的,所以每一步都要尝试三种可能的操作,过度的剪枝可能会WA。不过有一个很有效的剪枝就是:“实际上对于相同的敌人数与技能值,HP越多越好,因此只要记录HP最多的状态就可以了”(by pxhdg)。加上这个剪枝之后,原本350ms的程序一下减到了10ms。

ZOJ3447. Doraemon’s Number Game

downloadsource code (ZOJ3447.py) [greedy, BigInteger]

贪心。结果最大的策略就是:不断最小的两个数,计算后放回数集之中;相反的,结果最小的策略就是:不断取出K个(如果不足则取出全部)最大的数,计算后放回数集之中。题目结果很大,需要高精度。

Comments 12 Comments »

上上次上次的题解,补上这最后一部分。这次的三道题分别是我出的程序员六级阅读理解题Crack Me II;复数表达式解析计算题(误)Complex Calculator;和大自然数值积分题(大误)Bessel Function II

ZOJ3441. Crack Me II

[cpp + indent, sorting, set_difference]

题目就是要求写一个和这段天书一样的代码(ZOJ3441txt.c)功能完全相同的程序。

这一题是程序员四级阅读理解题ZOJ1584 Crack Me的加强版。首先说说这段天书是怎么来的吧,其实最初是一段非常简单的Haskell程序(ZOJ3441hs.hs)。然后我简单的用C重写的了一遍所有函数,于是得到了下面的C语言程序(ZOJ3441c.c),因为是按Haskell的思路来写的,所以几乎没有循环,全是递归。之后就是人肉宏替换了,其实写这段代码远比看懂它要辛苦啊。

如果你直接提交这段代码,会MLE,一看程序你就会发现,不断的malloc,完全不free。即使处理了内存泄漏,依然会TLE。有的时候可以通过只修改瓶颈代码来AC,比如ZOJ1584就可以这样做,不过这一题就行不通。

解决这道题的一种办法是通过够找各种sample,测出这段程序的功能。这是一个比较可取的办法,不过如果遗漏掉了任何一个地方都会WA,通常也会设置一些这样的陷阱,比如ZOJ1584在长度大于某个阈值的时候要数出”0″,这是很难测出来的。这段程序没有太xe的地方,不过对于负数的处理,也是要花点时间来找规律的。

另一种方法就是阅读代码了,这段代码的直接阅读难度要远远大于ZOJ1584。不过我们为什么要直接阅读呢?宏展开这种事编译器不就能做么,何必人肉?gcc -E命令就可以将宏展开,其实背后就是调用了GCC中一个叫cpp的程序,cpp是The C Preprocessor,只要

cpp ZOJ3441txt.c > ZOJ3441cpp.c

就得到了宏展开的代码,不过代码缺少良好的缩进,还是不可读,再利用代码格式化工具,比如indent,来处理一下

indent ZOJ3441cpp.c

这样代码(ZOJ3441cpp.c)的可读性就比较强了,唯一的麻烦就是变量名都没有意义,你可以在阅读的同时替换成有意义的名字。

Comments 2 Comments »

接着上次4道比较简单的题的解题报告写。这次是Detect the Virus IIAn Unusual Problem的解题报告,主要涉及如何在C, C++, Java, Perl, Python中使用正则表达式与及无损压缩算法

ZOJ3440. Detect the Virus II

[regex, topSort]

题目简单来讲就是通过上下文无关语法(context-free grammar, CFG)描述了virus。问一个字符串是否存在virus形式的子串。题目保证描述不会有环/递归。

这题用正则表达式(Regular expressions, regex)来做是再自然不过了,比如sample就等价于下面这段perl代码:

# subparta:=fg|g
$subparta = qr(fg|g);
# parta:=a|b|c
$parta = qr{a|b|c};
# partb:=d|e[subparta]h
$partb = qr{d|e($subparta)h};
# virus:=[parta][partb][partb]
$virus = qr{($parta)($partb)($partb)};

printf 'abcdefghijklm' =~ $virus ? "YES\n" : "NO\n";
printf 'nopqrstuvwxyz' =~ $virus ? "YES\n" : "NO\n";

当然,因为代码是顺序执行的,所以我们调整了几个record的顺序。顺插一句,如果是函数式编程语言的话,那顺序就完全无关紧要了。于是问题就是给定的字符串能否匹配题目所描述的正则表达式,不过因为输入的顺序不确定,所以要麻烦一点,不过即然没有环,一个拓扑排序就搞定了(ZOJ3440watashi2.pl)。

Comments 15 Comments »

ZOJ在建站105个月之后迎来了第一百场比赛。

””\\( ̄ー ̄) ( ̄ー ̄)//””

办一场比赛来庆祝一下,这个想法最先是姐姐在邮件中提出的:

所谓求人不如求己,我自己的记录里是有序号的,所以知道我们目前有98场原创比赛和10场Practice了!喂,要不要庆祝一下第100场呀??!^_^

而我们在ZOJ2.1提供了几个脚本语言的支持后,也一直想办一场“非主流”的比赛。所以便有了今天的 Let’s Celebrate the 100th Contest on ZOJ! — An Unusual Contest powered by ZOJ Staff 这场9道非同寻常的题组成的9小时9分9秒的比赛。题目的准备还是比较匆忙的,事实上除了hhanger的一道题以外,所有题都是最近几天出的。感谢参与出题和验题的navi, hhanger, quark, hsys猛犸也钻地等童鞋,也感谢大家的捧场和支持。


Let’s Celebrate the 100th Contest on ZOJ!
100A ZOJ3437 Very Hard Problem 6.89% (28/406)
100B ZOJ3438 Tripartite Graph 62.28% (71/114)
100C ZOJ3439 Substitution Cipher 7.86% (36/458)
100D ZOJ3440 Detect the Virus II 0.00% (0/26)
100E ZOJ3441 Crack Me II 2.06% (2/97)
100F ZOJ3442 Complex Calculator 0.00% (0/1)
100G ZOJ3443 Bessel Function II 0.00% (0/0)
100H ZOJ3444 An Unusual Problem 5.12% (2/39)
100I ZOJ3445 1KB 9.09% (4/44)

下面是解题报告:


剧透的分割线,看题解之前建议您自己先思考一下


Comments 11 Comments »


ZOJ Monthly, November 2010
A ZOJ3427 Array Slicing 21.05% (56/266)
B ZOJ3428 Bug Races 25.00% (2/8)
C ZOJ3429 Cube Simulation 22.94% (131/571)
D ZOJ3430 Detect the Virus 8.23% (40/486)
E ZOJ3431 Escape! 9.90% (21/212)
F ZOJ3432 Find the Lost Sock 18.38% (257/1398)
G ZOJ3433 Gu Jian Qi Tan 17.41% (39/224)
H ZOJ3434 Hiiragi’s Sticks 23.68% (9/38)
I ZOJ3435 Ideal Puzzle Bobble 4.87% (2/41)
J ZOJ3436 July Number 13.15% (15/114)

因为这一段时间考试、作业、Project实在忙不过来。所以原定的三题比较难的题目都没有挂出来,所以平凡的题目好像多了一点。最近事情好多好烦,希望快点应付过去……

ZOJ3427. Array Slicing

downloadsource code (ZOJ3427.cpp) [regex, simulation, slice, splice]

其实就是要实现一个list的__getslice__和__setslice__操作(pretty solution in python),或者说splice(more pretty solution in perl)操作。题目关于slice只贴了wiki上一段话,没有详细解释,不过sample给得很强,我以为slice是common sense,可是我错了。

输入有点小麻烦,其实scanf可以轻松搞定的啦,规模非常小,所以暴力什么的就好了。STL里的vector::insert和list::splice都可以直接做题目中的操作。题目说数字都是100,不过list的长度可是可以长到很长的哦,xe一点倒是可以让用数组的TLE,不过这是签名题,没有那么坏啦,sample应该是非常强的了 :-)

ZOJ3428. Bug Races

downloadsource code (ZOJ3428.cpp) [Number theory, Pythagorean triple, Euclid's formula, counting]

Comments 19 Comments »