[zz][ZOJ Monthly]October 2008解题报告

Connect4 Connect Four(Author: SONG, Yu[EZdestroyer])
题目的背景就是Linux下的同名游戏,两个人在7*7的槽里轮流扔棋子,每次棋子都扔进某一列,棋子会停在那列的最上面那个棋子的上面,某个player的4个棋子横、竖或者斜的连成一条直线就算赢了。
这个题,对题意的理解很重要,可以说,成功理解了题意,就成功了一半了。按照题目的意思,有以下三种数据:
1.完全不可能通过轮流放棋子达到的,这类要输出impossible。题目保证了,这种情况只有棋子个数不对和有棋子漂浮这两种情况,算是很大的简化。
2.可以通过轮流放棋子达到,但是当前状态已经是获胜的状态。这时又有两种情况,一种是最后一步导致获胜,应该输出XXX win,另一种是有一些棋子是在有人已经赢的情况下再放上去的,这种情况也要输出impossible。我们只要枚举最后放的棋子(只能是每列最上面的棋子,且拿掉后棋子数量要正确),看拿掉这颗后是否有人处于获胜状态就可以判断了。比赛时候我用了一个更麻烦的方法,不枚举,直接在图里找所有的长度大于4的条,如果有两种颜色的条,肯定impossible,然后求所有条的交集,交集为空,或者交集都不可能是最后摆上去的(上面有别的棋子压着),那么就是impossible。
3.这种情况就比较简单了,此刻游戏还没有结束,首先判断当前下棋的一步之内能不能赢。能的话就输出win。如果不能的话,枚举所有他摆放棋子的方法,只有所有方法对方都能赢,才输出对方win,否则谁都不赢。
这次的AC率是最低的,这题的第一个sample有点问题,其实是不可能通过轮流放棋子达到的,我们一直都没发现,对此说下Sorry,不过如果单纯按照题目意思做的话,是可以过的。

ConSame Continuous Same Game(Author: LAI, Li[ll861112])
题目的背景还是Linux下的同名游戏,在n*m的格子里,装满5种颜色的球,每次可以消除一块相连的个数大于1个的同色的球,得到相应的分数。现在采取贪心的策略,每次取最大的一块,有几块同样大的则取位置坐标字典序最小的那块,给定原始的状态,求最后可以得多少分。
很纯粹的模拟,求一块用DFS和BFS都可以,取所有块中最大的那块,如果按照先x后y的顺序枚举的话,不用考虑字典序最小的问题了,因为先找到的字典序总是更小的。然后是把这一块消去,模拟重力过程。特别需要注意的是,题目中说一整列都消失的话,右边的列会填补上来,估计很多WA的都是没有考虑到这个地方吧(我也是)。虽然是简单的模拟,不过要很快写对还是需要一定的Coding功力的。
这题一上来被HDU的快速MS了,可能是LAI, Li在HDU集训的时候出过的题?有点过分了-_-不过这个题也因此变成了最MS的题了。

DiabloII Diablo II Items(Author: HANG, Hang[hhanger])
题目的背景是鼎鼎大名的暗黑2,这题讲的是关于暗黑卖物品的一个问题。暗黑里面有两种物品,普通物品和魔法物品。普通物品只有一个普通出售价格,而魔法物品有两个出售价格,鉴定前的价格和鉴定后的价格,用鉴定卷轴鉴定魔法物品,物品的价格就变成鉴定后价格了。然后现在没有钱,有一堆物品要卖,其中有若干的普通物品和若干的魔法物品,其中魔法物品都是没有鉴定过的。同时,可以买无限量的鉴定卷轴(价格P0)。现在的问题是怎么卖东西才能让最后的总收益最大。
这题主要考察的是分析题目的能力。首先发现,所有的普通物品可以直接卖掉,因为他们只有一个价格。然后考察魔法物品(鉴定前价格P1,鉴定后价格P2),如果P1 >= P2 - P0,那么也可以把它们当作普通物品一样直接卖了,因为鉴定它们完全不会有任何的收获。然后,剩下的物品,鉴定后卖总是比不鉴定直接卖要赚钱的。我们可以发现,一旦我们有钱可以买得起一个鉴定卷轴,买一个来鉴定一个魔法物品然后卖掉后,钱会增加,于是可以继续买下一个鉴定卷轴。也就是说,一点身上的钱足够买一个鉴定卷轴,我们之后就可以良性循环把所有的魔法物品都鉴定了卖掉了。于是,问题就变成选择一些魔法物品来卖,让钱数超过P1,同时要保证亏损的最少(亏损指P2 - P1 - P0)。于是这就是一个普通的背包问题,每个物品有一个价值,和一个亏损值,要选其中的一些物品,使得价值总和达到一定的数值,同时亏损值总和最小,用一个dp就可以搞定了。
没有想到这个变成了第二MS的题,可能是因为代码量小的缘故吧~~

Painting Painting(Author: WANG, Naiyan[winsty])
题目的背景是wmm和wmm'mm自己发明的一个游戏,嗯,其实我们可以认为是用Logo海龟画画……题目是给定一个画笔的一些动作,包括向上下左右移动和提笔放笔几个动作,然后判断画出来的是0-9中哪个数字。
这是典型的乱搞题,有无数种方法可以搞的。首先要注意的是提笔放笔的判断,这个要注意了,可能一开始就提笔了,如果程序中要取坐标的,一定要只取那些画了实线的比划的坐标。然后数字是可以有大又小的,所以其实我们可以不管大小这个特征,只关心某些边的有无。所以我的方法就是把所有的线保存下来,同时计算出数字的size大小,最后查找某些线是否存在来判断是那个数字,具体的这里就不详细展开了,因为这个真的是一个很Open的题目,大家也可以提出自己的想法来。
传说中让教主挂了19次最后还过不了的题……ym winsty~~

Poker Playing Poker(Author: WU, Zejun[watashi])
题目的背景是空之轨迹里的扑克游戏,和梭哈很像,每次抽5张牌,由玩家选择换掉某些,不过不是和对手比大小而是根据牌本身的组合来决定赔率。根据同花、顺子和重复的数字分成很多种组合,每个组合的赔率不同,杂牌赔率为0游戏结束。题目中已知之后会出现的n张牌,问不使用超过n张牌的最优策略下可以赢多少钱。赔率上限是9999。——以上摘自Fire的解题报告,ym。
首先要完成的工作,自然是给定一副牌,按照题目给定的赔率表确定赔率。以前碰到这种扑克牌的判断题总是觉得很麻烦,真的写的时候发现其实也不是很麻烦,把一副牌的各种统计信息都计算出来(比如点数个数统计、花色数统计、点数排序序列等),后面的所有都好做了。不管怎么说,这块就是体力活。
有了上面的体力活工作,剩下的其实是很简单的线性dp,每次得到五张牌后,可以2^5枚举换掉哪些牌来进行状态转移,如果下一轮最优也只能得到杂牌,那就不进行下一轮了,否则继续,注意赔率别超过9999,做男人不能太贪心。如果第一盘无论如何都只能得到杂牌,那就只下1的注,否则下10的注。
其实这题发现了本质就很好写,有两个队都是比赛结束后几分钟就过了,可惜了一点,都被强大的外表给蒙蔽了。

Robots Unix Robots(Author: WANG, Yuting[wyest])
题目的背景依然是Linux下的同名游戏-_-地图上有人,机器人和垃圾堆三种东西。人只有一个,就是主角;机器人是自动移动的,总是朝着人的方向直线或者斜线移动一步;垃圾堆是不会动不会消失的,机器人走到垃圾堆的格子就变成那堆垃圾的一部分,机器人和机器人走到同一格就同时变成一个垃圾堆。给定所有东西的坐标,问人是否可以不动而最后没有机器人走到人的地方(全部变成垃圾堆了)。
因为机器人和垃圾堆的数量都不多,所以其实可以一次一次枚举碰撞。首先要解决的问题是得到两个机器人的坐标和人的坐标,如何判断两个机器人在移动的过程中是否会互相碰撞。这个还是比较好判断的,需要到达人所需的时间完全一样,同时在到人的途中要有相同的路径,这个写得好的话可以很轻易判断,而我写得比较繁琐。同样,也可以判断机器人是否会装上垃圾堆,这样,我们可以得到当前情况下所有可能的碰撞。如果没有碰撞,或者在最早的碰撞前已经有机器人到达了人的地方,直接输出NO;否则就模拟其中最早的那次碰撞(因为只有这次碰撞是必定发生的,其他的不一定),更新机器人和垃圾堆的数量和坐标,然后再重复上面的步骤枚举下一次的碰撞。如果最后所有机器人都发生了碰撞,就输出YES。上面的过程可以用一个优先队列来做,可以更好地实现,我没有写过。
这题不是很好写,不过要进去最前列,必须过了这题……

Snake Super Snake(Author: HANG, Hang[hhanger])
题目的背景自然是贪吃蛇游戏了,不过Super Snake这个名字确实Conan剧场版里面的某个过山车的名字……首先,题目的意思是,一个贪吃蛇在图上移动了t秒,然后给你他所到过的所有格子的t秒内被占用情况,求出每个格子的坐标。
题目保证了一定有解,而且是有spj的,所以只要输出任意一组解就可以了。同时可以发现,一组解平移一下,依然是符合要求的,只要满足所有坐标都在0~100之间就可以了。所以我们只需要求解格子和格子之间的相对位置关系就可以了,最后所有格子的坐标加一个偏移值即可。
观察贪吃蛇的移动,可以发现,每次有且仅有一个格子从N变成Y,同时,有且只有一个格子从Y变成N。接着考虑连续的两次移动,两次的从N变成Y的格子必定在图中是相邻的,而两次的从Y变成N的格子也必定是相邻的。于是,我们可以由原来的一个YN矩阵,得到一个格子与格子之间是否相邻的矩阵。可以证明,只要可以构造出一个图,满足这个相邻的矩阵,则必定是题目的解(可以按照YN矩阵模拟,因为满足相邻矩阵,所以每一步都是合法的,这个具体的可以自己在纸上画画推推)。
由相邻矩阵求图的过程可以使用搜索,我这里用了DFS。A格要和B格相邻,则A只可能在B的上下左右四个方向中的一个。首先,第一个格子的坐标是随意的,上面说过了,任意平移都是可以的。然后,我们要保证,后面搜索的格子,必须要和之前搜索过的格子中的某一个相邻。这一点是可以满足的,因为相邻矩阵保证了整个图是联通的,所以只要从第一个点开始做一次BFS(DFS应该也可以,我没试过……),按照被访问到的顺序给格子编号,这样所有格子就有一个顺序了,在这个顺序上进行DFS就可以满足之间的条件了,搜索速度会加快。
这题没有人过……首先搜索搜得不好的话很容易就超时了,最后IronGods的代码可能还有点bug导致WA了。

War3SG Whirlwind(Author: YANG, Kete[T_T])
题目的背景是魔兽里面的真三国无双,把关羽的大招看成一个半径为R的圆,敌人离自己距离为D,一开始就放大招,大招可以持续T2秒,关羽的速度是V1,敌人的速度是V2,敌人被大招打中T1秒就挂了,同时关羽有把退魔,可以使用一次使对方速度减半,退魔效果持续T3秒,关羽可以选择什么时候使用退魔。
这是一个有点复杂的判断题,需要很细心得想,很细心的写,不然很容易挂,可以这样子考虑:
如果T2 < T1,肯定杀不死敌人了,否则:
1 V1 >= V2。这种情况下,一旦关羽追上敌人,就可以一直追着敌人了,所以,目标就是尽快追上敌人,因此一开始就使用退魔,然后计算追上敌人的时间,看剩余的大招时间够不够杀死敌人即可。
2 V1 <= V2。这中情况下,又可以分两种情况考虑、
2.1 R >= D。敌人一开始在大招的范围内,再分两种情况考虑。
2.1.1 V1 < V2/2。就算用了退魔,关羽还是没有对方快,那关羽还是尽快用退魔吧,尽量延长敌人离开大招范围的时间,求出这个时间看是否大于等于T1。
2.1.2 V1 >= V2/2。用了退魔用,关羽速度比对方快,那先别急着用退魔,等敌人即将离开大招范围的时候再用,这样可以拖延更长的时间,同样求在大招内的时间是否大于等于T1。
2.2 R < D。敌人一开始在大招范围外,那还是必须马上使用退魔,争取能尽快追上敌人(退魔时间内追不上肯定杀不死了),等到追上后,就可以转化成2.1了。
今天第二坑的题,一定要细心写,Good Luck!

WW WW's game(Author: WAN, Wei[wanwei])
题目的背景是题目所说的那个Magical puzzle游戏,也是大家经常看到winsty玩的那个毛球游戏。当有三个贝壳连成一跳线的时候就可以消去,可以做的动作包括将一整行在行内移动任意格,或者将一整列在列内移动任意格。某个格子消去的时候被标上标记,题目给定原始游戏状态和一些动作,求做了这些动作后有多少格子被标记了。
和第二题一样,是考察coding的纯模拟题。首先要注意的是每次移动后,把所有能消去的都一起消去,然后是图中贝壳的下落的过程,这一过程不会发生消去,最后是用候补的贝壳填补图中的所有空白,注意是从按照从左到右,从上到下的顺序填补的,之后可以进行新一轮的消去,直到没有贝壳可以消去位置,才进行下一个动作。具体的模拟过程不难,就不详细说了。
还有一点要注意的是,候补的贝壳可能有很多,用数组存的话,开太小就会出现SF了,我是用vector存的,还有一种方法是用到哪读到哪,先把所有动作读进来,然后做,需要用候补的贝壳的时候每次读一个,最后所有动作结束后,把后面没用的候补贝壳读进来扔掉就可以了。
到比赛后期,大家纷纷发现了此题的本质,纷纷上去过了此题……

转载于:https://www.cnblogs.com/cnnbboy/archive/2008/10/04/1303864.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值