2016XTU算法专题个人赛2 题解
A. OpenJ_Bailian 4124 海贼王之伟大航路
题意: 编号为1-N的N个岛( 2<N≤16 ),给出每两个岛之间航行需要的时间,从1号岛出发,到N号岛结束,途中经过每个岛有且只有一次,问最短总时间。
解法: 直接搜的话
14!=87178291200
肯定会超时,考虑一些剪枝方法。我们发现对于1234……和1324……这两条路径,已经经过的岛都是1~4,而且第4个岛都是4,后续的搜索其实是完全一致的,如果1234所消耗的时间比1324少,那么当搜索到1324的时候就没有必要在搜下去了。具体实现上,可以用一个int记录当前状态已经经过的岛的情况(每一个二进制位代表每一个岛),再记录最后一个岛是哪个岛,对于这两个值相同的状态,对已消耗的时间较大的状态进行剪枝,这样DFS下去。
参考代码链接
B. CodeForces 197D Infinite Maze
题意: 一个
n × m
的迷宫,包含墙和可通行的部分。对它进行无限扩展(
(x,y)
是墙当且仅当
(x%n,y%m)
是墙)。问从标记为S的地点开始能否走无限远。
解法:
翻译:
答案是“Yes”当且仅当从起始点S能够到达两个不同的格子,而这两个格子在初始的迷宫上有着相同的位置。
证明:如果存在这样的两个格子存在,先移动到第一个格子,然后无穷地重复从第一个格子向第二个格子的移动。另一方面,如果无穷远的路径存在,在这条路径上我们显然可以找到这样的格子。
怎样判断它们是否存在?从起点开始DFS搜索,对于访问到的每一个格子,令
visit[x%n][y%m]=(x,y)
。现在DFS尝试进入格子
(x,y)
,
visit[x%n][y%m]=(x,y)
包含数据,而
(x,y)≠ visit[x%n][y%m]
,这样我们就找到了这些各种,它们就是
(x,y)
与
visit[x%n][y%m]
。注意到DFS不会访问超过
nm+1
个格子(抽屉原理),所以复杂度为
O(nm)
。
C. HDU 5336 XYZ and Drops
==以下文字来源于l(iu)x(in)dd==
题意:
类似于十滴水游戏,一开始会从(x,y)点扩散出4个方向的小水珠,题目也会给你一些大水珠,每个大水珠都有他自己目前的水滴数,如果
某个大水珠的水滴数大过4,就会爆掉,并同时向四个方向发射出小水珠,小水珠每秒移动一格,题目问T秒后原本各个大水珠的状态。
解法:
这题其实模拟很简单的,但是有个地方坑,就是如果一个小水珠触发爆了某个大水珠,那么此时也刚好到达这个大水珠的小水珠也会消失,相当于多个小水珠同时到达一个大水珠,大水珠爆了,所有此时在这里的小水珠都没有了,不然会多小水珠的
===以上文字来源于lxdd==
D. OpenJ_Bailian 2755 神奇的口袋
题意: n个物品
(1<=n<=20)
,每个物体体积在1到40之间,选出几个物品使得总体积为40,有多少种方案?
解法: 直接dfs暴力枚举每个物品选或不选,
220=1048576
,可做,结果54ms。优化的话可以先进行排序,然后从小到大扫过去枚举选或不选,如果选择当前物品后总体积就>=40就不需要再搜下去了,剪枝后36ms。
E. HDU 1180 诡异的楼梯
题意:
m∗n
的地图
(0<=M,N<=20)
,’*’表示障碍物,’.’表示走廊,’|’或者’-‘表示一个楼梯,’S’是起点,’T’是目标。梯子|连接上下连个格子,-连接左右两个格子,移动到相邻格子或者楼梯连接到的格子需要1分钟,梯子的状态(|或-)每分钟互换,梯子上不可停留。问从起点到终点最少需要多久。
解法: 在普通的BFS搜地图的基础上,由于梯子有两种状态,分别对应时间为奇数和偶数的情况,所以visit数组也要分开考虑,故应该有
visit[时间奇偶][行][列]
。对于每个状态,可以考虑停在原地的情况,和4个方向走动,如果走到的地方是楼梯,则根据时间、移动方向、楼梯类型来判断能否通过,能通过则往相同方向再走一步,否则移动不合法。注意无论是直接移动到下一步,还是从梯子上再走一步,都要判断是否走出棋盘、是否已访问、是否为障碍的情况。