这周依然看的是搜索,经过大量题目的阅读和积累经验,我对搜索有了更加深入的认识。这周课调成线下了,学习效率有了明显的提升,可能是自己的学习习惯问题,一直上的都是线下突然线上确实不适应。这周也是看了大量的习题,也上手做了一些。
目录
洛谷P1415
(题目链接)
题目大致是:一矩形阵列由数字 00 到 99 组成,数字 11 到 99 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。
题目的思路是:
-
要找到细胞块,当一个细胞块被 00 围住 的时候,这个就算是一个细胞块
-
细胞块只能是 上下左右 ,斜角是无用的
-
当你使用 dfsdfs 的时候,注意判断使用的边界是不是 当 Map_{i,j}Mapi,j 的时候 1 \le i \le n, 1 \le j \le m1≤i≤n,1≤j≤m
搜连通块,用bfs做起来比较容易实现,用dfs也可以,但处理起来比较麻烦,我没写出dfs的写法,看到题解大佬中有用dfs写下来的也是深感佩服。实现的关键在于这两个函数
void init() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> Map[i][j];
return;
}
void dfs(int x, int y, int block) {
flag[x][y] = 1;
for (int i = 1; i <= 4; i++) {
int x2 = x + X[i];
int y2 = y + Y[i];
if (x2 >= 1 && x2 <= n && y2 >= 1 && y2 <= m && flag[x2][y2] == 1 && Map[x2][y2] != '0')
dfs(x2, y2, block);
}
return;
}
洛谷P1331
(题目链接)
题目:在一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。
思路:也是用广搜找到最优解后,就不用继续搜了,用两个for找出每一个‘#’处的附近是否合理即可。我第一开始没有想到这样,苦苦试了很多遍,开始还脱离了循环,后来想到和细胞分裂的一个题类似,于是用bfs就行了。在这个题中,难点在于两艘船相邻,判断他们两个不是一艘船,这个问题,这样直接跳过就行。
洛谷P1451
(题目链接)
这道题很多大佬用到了分治,由于我知识储备浅陋。于是去了解下分治,分治简而言之,就是把一个复杂问题,分解为多个较为简单的问题。在学到的递归,就是用的这个原理。当然搜索也是可以的。
洛谷P1706
(题目链接)
题目:按照字典序输出自然数 11 到 nn 所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
这道题用深搜可以解决问题,逐个的确定数字,最后输出。看到大佬也有用暴力枚举的,真是大力出奇迹。用深搜,就是先找出所有的结果,判断是否用过,用过标记,最后回溯。
洛谷P4961
(题目链接)
这道题就是和扫雷一样, 用b函数初始化数字,接着统计周围八格无空格且本身为数字(需要单独点一次)的格子,这些格子每一个都要3bv++。
感悟:
这两周把时间用到搜索的比较多,算是有了个深刻的理解,对于搜索和其他的算法的结合。还是希望自己深入学习更多知识,题不是解出来就完了,而且要寻求最优解,这是比较锻炼人的地方。