几个月不参加 Codeforces 的比赛了,没有紧张的气氛,做得有点没感觉。前两题水过,第三题想复杂了,第四题当时没有想法,最后一题没心情看。比赛 URL: http://codeforces.com/contest/151 .

A 题 151A Soft Drinking 的背景是几个好朋友在一起喝饮料。其问题的实质是这样的:要制造一种物品,需要不同数量的不同原料;给出各种原料的数量和每件物品需要每种原料各多少,然后求最多能制造多少个这种物品。

B 题 151B Phone Numbers 的背景是几个好朋友的电话本。某市的电话是 6 位数,都是以 22-22-22 这样的形式给出。有三种类型的电话,一种是计程车电话,其特点是电话每个数字都相同;一种是披萨外卖电话,其特点是几个数字是递减的;其余的是妹子的电话。最后问,拥有计程车的电话、披萨外卖电话和妹子的电话最多的人分别是谁。

后来看到别人的博客,里面说 B 题如果没有人有某种类型的电话,那么这个时候要把所有人的名字输出。但是我的代码里没有考虑这种情况,似乎这样也 AC 了。

C 题 150A Win or Freeze 说的是两个人玩游戏,一开始 1 号玩家面临一个数 p, 如果他能写出 p 的一个非平凡因数 q, 就可以轮到玩家 2, 让他写出 q 的非平凡因数 r, … 直到某个玩家不能写为止,然后那个不能继续写数的玩家获胜。输入数据给出数 p, 问哪个玩家能获胜;如果 1 号玩家获胜,第二行要输出 1 号玩家应该写的数字是什么。如果 1 号玩家一开始就赢了,那么就在第二行输出 0.

这题一开始我的想法是,如果一个数是质数或者 1, 那么 1 号玩家就没法写数了,他就直接赢了。如果开始的数是两个质数的乘积,那么 1 号玩家只能写其中一个质因数,那 2 号玩家就赢了。如果是 > 2 个质因数,那 1 号玩家可以找出其中两个质因数,相乘,写出那个数给 2 号玩家,这样 2 号玩家只能写一个质数,然后 1 号就赢了。

这题的数据范围比较大,当时我居然想到用 Miller-Rabin 算法。开始的时候 pretest 7 总是过不了,赛后发现那个数据是 445538663413, 是一个比较大的质数,似乎让 Miller-Rabin 判断了几次都没判断出来,比赛时我也没发现,后来用一些小 trick 也算解决了这个问题(只是不能一开始就判断出是不是素数,浪费了一些时间罢了,算法看起来似乎还是对的)。后来赛后的 test 28 把我这题 WA 了,数据是 9999926826034, 这是 2 和一个 4999963413017 的乘积,似乎后者是质数,然后 Miller-Rabin 也把它判错了。

其实这题根本不用这么复杂的方法,直接试除就可以了,管你质数不质数的,找到两个约数,发现原数除完它们后不是 1, 玩家 1 就赢了;反之若是 1 就玩家 2 赢。如果找到 [latex]\sqrt{p}[/latex] 还是没有约数,那 p 就是质数了,还是玩家 1 赢。

D 和 E 到时候再研究一下吧,要加油啊。

2012 年 2 月 19 日更新D 题 150B Quantity of Strings 的题解请点击这里

原创文章,转载请注明来源:http://euyuil.com/3254/codeforces-round-107-div-2/