Google Code Jam 2008 Round 3 解题报告

  

Problem A: How Big Are the Pockets?

    这题的意思是要求一个闭合的多边形外,有多少点的上和下或者左和右都有多边形的边界。

    假设我们一行一行地来扫描这个多边形,我们从最左边开始,这时候我们的点在多边形外。

当我们第一次穿过多边形的一个边界的时候,很明显,我们就进入了多边形的内部,当再次遇到一条边界的时候我们又在多边形的外部了。通过这样的方法,我们可以发现当我们把某一行的边界按照坐标排序后第偶数条边界同第奇数条边界之间的所有点都是在多边形外部的,并且他们有左右两个边界。对于竖直方向上我们也可以用类似的方法处理。

 

Code

 

 

 

 

Probles B: Portal

    题目的意思就是在一个迷宫内从一个点以最短的步数走到另一个点,不过我们可以使用传送门。

    基本的方法是BFS。关键在于怎么记录状态,起初我是想记录下当前人所在的坐标以及两个门的坐标以及门的方向,这样需要 17^6×8的空间,显然这个方法不太好。在仔细想想,我们发现第一枪是可以随便打的,可是当我们打出第二枪的时候,我们就一定会朝着第二枪所打的方向一直走过去,并穿过那个传送门,应为如果不这样走的话,那么,那个第二枪打的是没有意义的。进一步思考,我们还会发现,第二枪一定可以是贴着墙打的,不是吗?

这样我们我们就需要记录到某个点坐标,以及到该点时所有可能有门的位置。然后当我们走到一面墙的时候,就可能到其他所有有门的位置了。

 

 

Code

 

 

Problem C: No Cheating

    这题是很经典的一个问题,比赛的时候我竟然还不知道。

将这个图上的点染成黑白两色,奇数列点染成黑色,偶数列点染成白色。所有冲突的点之间连一条边,我们发现只有黑色点和白色点之间有边。于是问题就转化成了求一个二分图的最大独立集。类似的匹配问题有很多,如PKU 3020 (最少边点覆盖) PKU 3041(最少顶点覆盖)

 

我的代码忘了存了,这是bmerry的

 

Code

 

 

Problem D: Endless Knight

    题目是一个马,走日字行,不能回头,问从一个棋盘的左上角走到右下角有多少种方法,另外棋盘中还有R(R <= 10)个点是不能走得。

    首先我们考虑没有不能走的点的情况,从(1,1)走到(H,W),总共需要走的步数是 Step = (H-1 + W-1) / 3,当然如果不能整除的话,就无法走到终点。如果能走到的话方案总数就是 C[step][H-1-step] (C[i][j] 为组合数)。然后我们要做的就是去除掉这么多方案中所有经过了R1个或多个点的情况,这里我需要用到容斥原理,具体方法见代码。

最后还有个需要解决的问题就是如何计算 C[m][n] % pm,n的范围达到10^8

公式是 C[m][n] % p = C[m/p][n/p] * C[m%p][n%p] % p。别人告诉我的, 有谁知道怎么推导的麻烦告诉我一下子。

 

 

 

Code

你可能感兴趣的:(Google)