![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
搜索
AC_Arthur
Die luft der Freiheit weht
展开
-
UVA 1267 - Network(贪心DFS)
题目链接:点击打开链接题意:一开始只有一个结点上有一个服务器, 为了让所有叶子结点距离服务器的距离不超过k, 我们在非叶子结点上添加服务器, 问最少添加多少服务器。思路:贪心。 将第一个服务器所在结点作为根结点, 向下拓展, 记录父子关系, 将叶子结点的深度排序, 从最深的结点开始向上找k个距离的父节点, 安装服务器, 并进行一次DFS, 将所有距离它不超过k的结点标记。细节参见代码:原创 2016-02-24 13:31:48 · 1130 阅读 · 0 评论 -
POJ 3087 Shuffle'm Up(BFS)
很多人不觉得这是个搜索,说是模拟,其实这是没有理解搜索的实质。搜索就是扩充状态和状态的转移。 该题可以将每次洗牌后的情况当成状态进行BFS,只不过这个BFS每次只有一个决策可以拓展罢了,这样当出现状态重复时将无解。那么为什么要用BFS呢? 因为循环结的周期未知,用BFS可以减少递归的无目的性。 而且该题比较简单,每层只有一个拓展点,所以用什么方法倒也无所谓。关于对状态的判原创 2015-10-11 10:54:01 · 903 阅读 · 0 评论 -
FZU 2150 Fire Game (暴搜/ BFS+DFS)
对于该题,显然,如果有两个以上的连通块,那么将无法烧尽所有草地。 所以我们可以先用DFS判断连通块个数,然后枚举两个人防火的地点,进行BFS求最短时间。注意,题目中已经给出了提示:两个人可以选择同一个格子。 我就是在这里WA了好久,因为如果只有一个格子是草地的话,如果不让他们坐标相同,那么将不会进BFS,那么答案将是INF。细节参见代码:#include#include#i原创 2015-10-11 21:44:44 · 649 阅读 · 0 评论 -
POJ 3279 Fliptile(暴力)
该题乍看很难,如果要是dfs搜的话恐怕无法快速解决问题。但是仔细分析一下的话,会发现 : 首先,对于每个格子,翻转1次以上是没有意义的,等价于没有反转或反转一次。 所以答案不是1就是0其次,如果对答案进行暴力,再检查该答案是否符合要求,那样枚举的时间复杂度高达2^30,还是无法解决该题。 但是我们发现,对于任意一个格子,对它有贡献的只有它自己和上下左右的格子。 所以我们可以只枚举最上原创 2015-10-10 15:20:08 · 1644 阅读 · 0 评论 -
HDU 2612 Find a way(BFS)
一开始想法比较傻,对每一个KFC为起点BFS,后来发现其实我们只需要对这两个人为起点BFS一遍就行了,将遇到的每个KFC记录在vector里,但是WA,后来又发现不需要保存的vector里,直接用两个数组记录路径就OK了,成功AC。 之前那个方法肯定也行,不知道哪里出现了BUG。。。细节参见代码:#include#include#include#include#include原创 2015-10-09 17:11:40 · 471 阅读 · 0 评论 -
HDU 1495 非常可乐(BFS)
很简单的BFS,由于一个小小BUG,调了一个晚上~再次接触搜索专题,有了一丝不一样的感觉,再看紫书,才明白其中的一些精华 。其实,搜索和动归简直是密不可分,什么BFS啊DFS啊其实都是搜索,手段都是一样的,目的也是一样的。对于搜索,现在逐渐重视到了一个之前忽视的东西:状态。 其实搜索的就是状态,定义的也是状态,剪枝剪掉的还是状态,记忆化搜索保存的也是状态。对于一个搜索,你会遍原创 2015-10-09 21:36:54 · 663 阅读 · 0 评论 -
POJ 1321 棋盘问题(搜索)
暴力搜索,只要把握住几个地方就行了 :1. 我们可以按照行来放置,因为任意两个棋子不能同行,所以对于每一行,要么放,要么不放。2.我们可以用一个数组记录每一列在此之前有没有棋子,其实就是一个更简单的八皇后问题。这样已经足够通过本题的数据了,但是我们还可以添加一个剪枝:如果当前棋子数+之后的行数 细节参见代码:#include#includeusing namespace s原创 2015-10-06 17:39:01 · 512 阅读 · 0 评论 -
变形课(DFS)
水题#include#include#include#include#include#include#include#include#include#includeusing namespace std;typedef long long ll;const int mod = 1e9 + 7;const int INF = 1e9;const int maxn =原创 2015-10-20 17:12:07 · 692 阅读 · 0 评论 -
POJ 2251 Dungeon Master(bfs)
简单的BFS模版题。 重新审视BFS和DFS以及DP,发现三者之间存在莫大关联,总的来说,都是对状态的深入理解,以及记录状态再利用,利用状态扩展其他可能状态,以及利用状态剪枝 。 都是对状态的深入理解。细节参见代码:#include#include#include#include#include#include#include#includeusing namesp原创 2015-10-06 19:56:49 · 647 阅读 · 0 评论 -
POJ 1426 Find The Multiple(dfs)
一开始被m的位数吓到了,以为要用高精度 。 后来发现答案不会超long long,也不知道是数据水了还是本来如此。这样就很简单了, 搜索深度最多19层,每一层只有两个决策: m*10 和m*10+1 。细节参见代码:#include#include#include#include#include#include#includeusing namespace std;t原创 2015-10-06 21:37:58 · 570 阅读 · 0 评论 -
POJ 3414 Pots (BFS)
如果用状态这个术语来表示的话,那么显然,两个杯子中水的情况对应了一个状态。 所以用BFS很容易求出最小值。 该题的打印路径其实和紫书上第6张中迷宫问题用的方法是一样的,用一个父亲指针记录路劲个,这样就可以很方便的打印出路径。细节参见代码:#include#include#include#include#include#include#include#include原创 2015-10-11 19:35:13 · 578 阅读 · 0 评论 -
UVA 11624 Fire! (BFS)
该题是一道比较简单的BFS, 难点在于火会蔓延,那么我们不妨分开进行两次BFS,一次标记好每一处第一次被火烧到的时间,第二次就可以用这个时间标记来进行BFS了。之前也有过一次记录下时间标记来利用的情况 ,算是个技巧吧。细节参见代码:#include#include#include#include#include#include#include#include#inclu原创 2015-10-13 16:09:08 · 538 阅读 · 0 评论 -
Educational Codeforces Round 7 E. Ants in Leaves(DFS+贪心)
题目链接:点击打开链接题意:给出一棵n个结点的树, 每个叶子结点上有一只蚂蚁, 每秒每只蚂蚁可以向相邻结点走一步, 同一时刻同一结点上只能有最多一只蚂蚁(根结点除外),根结点为1, 求所有蚂蚁都移动到1上的最小花费时间。思路:很容易想到,采取贪心的思路就行了, 那么只要不断向上走就行了, 因为根结点比较特殊, 我们只考虑它的子树, 对于它的每一棵子树, 先dfs处理出所有结点的深度,然后对原创 2016-02-13 14:32:22 · 2056 阅读 · 2 评论 -
UVA 10054 - The Necklace(欧拉回路)
题目链接:点击打开链接题意:n个珠子,每个珠子的两半由不同的颜色组成。 只有相同的颜色才能接在一起, 问能否组成一个一个项链。思路:如果将一个珠子看成是一条连接两个顶点的无向边,那么本题就变成了求无向图是否存在欧拉回路。 对于无向图, 如果所有点的度数都是偶数并且图是联通的, 那么就存在欧拉回路。 那么从任意一个点开始走都将走完所有道路并回到起点。细节参见代码:#includ原创 2016-02-09 21:23:16 · 3033 阅读 · 0 评论 -
UVA 10047 - The Monocycle(BFS)
题目链接:点击打开链接题意:从起点到终点,每秒可以选择前进、向左、向右转, 每前进一格轮子转到下一个颜色, 一共5中颜色, 开始的时候绿色接触地面,朝北, 要求最后也绿色接触地面,求能否到达目标点以及最短时间。思路:和普通BFS相比,多了两个附加条件,所以要将状态表示全面,也要对应加两维。 水题。细节参见代码:#include#include#include#include原创 2016-02-08 22:14:11 · 2092 阅读 · 0 评论 -
HDU 3085 Nightmare Ⅱ(双向BFS)
经典的双向BFS, 可以使得世间复杂度大大降低。因为男生和女生每秒走的步数不一样,所以我们可以利用BFS的特点,以每一层作为一个单位来BFS细节参见代码:#include#include#include#include#include#include#include#include#include#include#include#include#include原创 2015-12-02 21:29:45 · 844 阅读 · 0 评论 -
HDU 2337 Escape from Enemy Territory(BFS+二分优化)
该题比普通的BFS多加了一些限制条件。 一个是:首先要满足在这条路径上距离敌人的最近距离尽量大。 第二个是:路程尽量最短。最短路当然是BFS求, 可是怎么确定这个最近距离呢? 我一开始搞了个优先队列, 按照这个值从大到小排序, 可是后来yy了一下,发现是不对的, 因为当前最大,不一定后来还是最大的路径, 所以会丢失最优解 。后来想了一个方法:再开一个数组记录之前经过这个点的最近距离,原创 2015-11-27 22:41:56 · 834 阅读 · 0 评论 -
Codeforces Round #297 (Div. 2) E. Anya and Cubes (双向DFS)
首先思考最暴力的方法: 我们用DFS直接搜索所有可能解, 那么对于每一层,有3种决策: 不选这个数, 选择这个数, 选择这个数的阶乘。 递归深度最大25, 时间复杂度O(3^25), 太大了, 要想办法降低时间复杂度。 还记得之前的简化版吗? 我们在四个集合中每个集合选择一个数字相加,问是否等于一个数S, 我们的方法是预处理两个集合中所有的情况,然后二分。 该题也可以采取相同的策略: 进原创 2015-11-25 22:20:54 · 803 阅读 · 0 评论 -
HDU 1043 Eight(BFS打表+状态去重)
该题是一道经典的八数码问题,难点在于对状态的定义和判断该状态是否访问过。 紫书上列举了三种方法:set存,hash,编码解码。编码解码的原理是利用了康托展开,我们都知道,对于一个长度为n的序列,其全排列一共有n!种,利用康托展开我们可以快速的求出一个排列是按照字典序的第几个排列。这样我们就将每个排列(状态)与一个n!内的整数对应起来了。 但是这样还是会超时,无奈我想到了既然终点状态固定,原创 2015-10-29 14:01:58 · 713 阅读 · 0 评论 -
HDU 2102 A计划 (BFS)
简单BFS,注意好状态转移过程 即可,还有就是一旦踏入传送机,立刻会被传送,所以要立刻改变z坐标细节参见代码:#include#include#include#include#include#include#include#include#include#includeusing namespace std;typedef long long ll;const in原创 2015-10-13 22:05:52 · 701 阅读 · 0 评论 -
HDU 2181 哈密顿绕行世界问题(水DFS)
该题乍看很难的样子,其实就是个水DFS,因为要打印所有可能方案,所以无法剪枝,直接遍历所有可能情况就行。细节参见代码:#include#include#include#include#include#include#include#include#include#includeusing namespace std;typedef long long ll;cons原创 2015-10-28 16:11:51 · 731 阅读 · 0 评论 -
HDU 1016 Prime Ring Problem(水题纯暴)
直接DFS就行,连剪枝都不要。 因为要打印所有可能解,也没法剪枝 。因为相邻的元素之和要求互素,所以能成立的解很少,解答树并没有想象中那么大。细节参见代码:#include#include#include#include#include#include#include#include#include#includeusing namespace std;type原创 2015-10-20 16:23:41 · 615 阅读 · 0 评论 -
HDU 4771 Stealing Harry Potter's Precious(BFS)
就是一道简单的BFS,由于要拿到所有宝藏,那么我们可以状态压缩宝藏集合, 为了使得状态表示完整,就需要在状态数组d中多增加一维。比较常见的题型。细节参见代码:#include#include#include#include#include#include#includeusing namespace std;typedef long long ll;const int I原创 2015-10-18 08:55:40 · 644 阅读 · 0 评论 -
1601 - The Morning after Halloween(BFS)
该题时限还是比较宽的,但是如果纯BFS还是会超时,所以要注意题目中的暗示 :任何一个2*2子网格中至少有一个障碍格 。 这表明障碍格有很多,那么重复搜索这些障碍格将会造成极大的浪费(因为我们开了三维数组记录三个鬼的状态,格子越多,状态也会以三次方的速度增加)。 所以我们可以将不是障碍的格子提出来再建一张图,用邻接表的方式。那么怎么来建图呢? 受坐标离散化的启发,我们可以将每一个有用的格子映原创 2015-08-11 09:00:23 · 1281 阅读 · 0 评论 -
1343 - The Rotation Game (IDA*算法)
紫书上给的是状态空间搜索,其实本题也可以用IDA*算法,因为其符合IDA*的特点 : 求最小迭代次数 。根据旋转的规律,我们可以用几个数组来储存向各个方向旋转时改变哪些量,用来维护旋转这个操作 。另外就是估价函数:当前出现在中间八个格子中次数最多的数字设为t ,那么剩下的迭代次数就是8 - t , 如果它加上已经迭代的次数d > maxd ,则应当剪枝 。另外想到了一个估算回溯法的时间复原创 2015-08-11 20:51:21 · 1033 阅读 · 0 评论 -
1374 - Power Calculus (迭代加深+剪枝)
题目要求乘除法的最少次数,其实就是一个数组中一开始只有一个数:1 ,每次可以从数组中取两个数(可以取同一个数)相加生成一个新数加如数组 。那么显然这是一个迭代加深搜索,从小到大枚举深度上限 。为了降低时间复杂度,我们要尽量的减少迭代次数,所以我们优先做加法,并且优先将最大的两个数相加,这样可以最快的接近目标 。当然,有一个很显然的剪枝: 当每次取最大的两个数相加仍然小于n时要剪枝 。因原创 2015-08-10 20:10:19 · 939 阅读 · 0 评论 -
hdu-4127 Flood-it!(IDA*算法)
今天做的福州赛区区域赛的题目重现,一整场都在抠这道题仍然无法AC,时间卡的很紧,不过其实也是自己的搜索学的实在太差,紫书上刷的最少的就是第七章的题 。我一开始就看出了这道题需要IDA*算法,但是昨天才看的还没能深入理解,通过赛后补这道题,感觉整体思路有了一个新的突破 。IDA*算法就是迭代加深搜索和A*算法的结合,迭代加深搜索非常简单,就是从小到大枚举深度上限,适合求解深度未知的或者像该题原创 2015-08-08 08:57:24 · 1906 阅读 · 0 评论 -
Hopscotch.(POJ-3050)
穷竭搜索。。无法剪枝。#include#include#include#include#includeusing namespace std;int a[10][10];char A[15];int dx[] = {0,1,0,-1};int dy[] = {1,0,-1,0};set G;void dfs(int i,int j,int cur) { if(cu原创 2015-04-16 16:40:56 · 901 阅读 · 0 评论 -
Meteor Shower(POJ-3669)
这道题的输入部分,写错了一个符号,结果就各种WA,实在不应该,既然写一次就应该仔细,力求一遍成功。思路:用vis数组记录每个点被炸弹炸到的最近时间。用d数组记录当前时间。当d当然,因为炸弹会波及四周,所以数组应该稍微开大一点。#include#include#include#include#include#includeusing namespace std; in原创 2015-04-14 14:30:28 · 1239 阅读 · 0 评论 -
Backward Digit Sums(POJ-3187)
本来以为会超时,看来是想多了,63ms,看来对时间复杂度的判断能力还是不行啊。这个题正是next_permutation()函数的用武之地。#include#include#include#include#include#includeusing namespace std;int n,sum,a[100],A[100];int main() { scanf("%d%d原创 2015-04-14 16:24:21 · 1086 阅读 · 0 评论 -
Smallest Difference(POJ-2718)
暴搜一下就行了,确实也没法优化什么。 不过枚举一半,另一半用next_permutation()函数应该是会快一些的。#include#include#include#include#include#includeusing namespace std;int T,a[20],n,vis[20],tot;int A[20],B;void dfs(int cur) {原创 2015-04-14 15:45:46 · 757 阅读 · 0 评论 -
Red and Black.(POJ-1979)
DFS水题。#include#include#include#include#includeusing namespace std;int dx[] = {0,1,0,-1} ;int dy[] = {1,0,-1,0} ;int n,m,maxn;int vis[25][25];char s[25][25];struct pa{ int r,c;};voi原创 2015-04-11 16:50:45 · 737 阅读 · 0 评论 -
211 - The Domino Effect(暴力)
很水的暴力,直接暴就行,连剪枝都不需要 。 紫书上描述的很少,只看紫书肯定觉得不知所云,建议大家读读原文 , 看好输入输出格式,明白了题目意思就很好做了 。大致的意思就是如果相邻的两个数字可以出现上面的组合就能换成对应的骨牌,但是要注意,任意答案中只能出现2个骨牌的值相同,所以加个数组判重就行了。细节参见代码:#includeusing namespace std;int kase原创 2015-08-12 10:24:05 · 874 阅读 · 0 评论 -
307 - Sticks (深搜 + 剪枝)
由于要求最小长度,所以可以从小到大枚举木棍的长度 ,显然,木棍最小值为所给木棍的最大值 。 所以从该值开始枚举木棍长度,则木棍如果大于所有木棍之和,那么答案肯定就是所有之和了 。该题时间卡的比较紧,需要努力剪枝 ,总的来说就是找到几种肯定不会得到最优解的情况,然后直接回溯 。细节见代码:#includeusing namespace std;const int maxn = 100原创 2015-08-12 21:43:28 · 1075 阅读 · 0 评论 -
HDU 3533 Escape(BFS)
一看就是BFS,但是该题不是很好处理。 给的时限很宽裕,所以对于各个炮塔的状态判断其实是可以在BFS里现算的。我一开始想将各个炮塔在d秒范围内的状态先算出来然后存在数组中,结果MLE,换了个bool型的数组终于勉强存下了。 然后就开始WA,后来才发现原来子弹的途中只要有炮塔就会被阻挡,而不是炮塔被击中时才阻挡子弹。 这样就可以AC了,还有就是HDU的di'scuss里的数据是错误的,炮原创 2015-10-17 10:54:52 · 662 阅读 · 0 评论 -
Codeforces Round #325 (Div. 2) D. Phillip and Trains (BFS)
一开始看这题,还以为是DP,后来写完记忆化搜索之后发现结果怎么也不对,仔细一想,无论时间复杂度还是状态转移好像都不想DP。 后来想了一下,发现应该是BFS(DFS的盲目性太大,而BFS则可以在最早的时刻剪枝)。 所以我们不妨先用一个数组记录下所有列车在各个时间点的状态,然后用来在BFS中做判断。细节参见代码:#includeusing namespace std;typede原创 2015-10-16 17:26:19 · 620 阅读 · 0 评论 -
11212 - Editing a Book(IDA*算法)
又一道迭代加深搜索,从小到大枚举上限 。 关键的剪枝部分是写出启发函数,这个比较难。。不过每次剪切后,不正确的数字个数最多减三还是很好理解的,因为我们算不正确数字个数的方法是看当前数字+1是不是等于下一个数字 。 所以每次剪切最多只有3个数字的后继数字发生了改变。 那么 剪枝条件就显而易见了 。代码如下:#includeusing namespace std;const in原创 2015-08-05 10:16:24 · 1167 阅读 · 0 评论 -
11214 - Guarding the Chessboard(暴力搜索)
IDA*算法, 从小到大枚举深度上限,不过该题是有深度上限的,题目中的第一个样例表明:最多需要5个皇后就可以覆盖整个棋盘 。 利用紫书上的技巧,我们可以快速的判断任意两个棋子是不是在同一行、同一列、同一对角线 (详情见紫书P193那两个图)。 这样之后暴力搜索就可以了 。 每一层需要O(nm)的复杂度,但是实际上并不需要那么大的复杂度 。和八皇后问题类似 , 当前行之前的行已经放置了皇后,原创 2015-08-05 08:14:33 · 848 阅读 · 0 评论 -
12558 - Egyptian Fractions (HARD version)(IDA*算法)
IDA*算法,迭代加深搜索和A*算法的结合 。迭代加深搜索适用于那些没有明显深度上限的题目,将深度从小到大枚举,直到找到最优解 ,减小了深搜的盲目性 。A*算法需要一个乐观估价函数,在这个函数里寻找一个代价最小的点去搜索,所以时间复杂度都浪费在这个上面了 。其实我照着紫书上巧的,感觉很容易,实际上其中的算法思想是要静下心来仔细研究的,练ACM这么久了,深深感到这个竞赛是那么的迷人,又是原创 2015-08-04 20:04:27 · 717 阅读 · 0 评论 -
hdu-5025 Saving Tang Monk (BFS + 状态压缩)
该是比较简单的BFS的 。 难点在于多了两个限制条件 : 必须按照顺序捡拾钥匙 ; 杀死蛇消耗2单位时间,蛇只会被杀死一次 。因为在拿到第n把钥匙前必须拿到第n-1把,所以只需要加一维大小是11的维度来维护当前拿到的钥匙情况就可以完整的表示所有状态了 。但是还有蛇的条件,所以不妨在结构体里加一个正数,将其压缩成一个集合表示第i只蛇是不是被杀死了 。 所以事先对所有的蛇进行编号就行了原创 2015-08-14 19:39:16 · 991 阅读 · 0 评论