3月1-第六次机试课记录
作者:互联网
搜索
坑
搜索的题目一般代码比较长,所以需要良好的编码习惯,写清楚变量名,以及一定的注释和debug信息
长函数拆开写,好debug,养成正确的习惯
变量名称全局和局部有区分下最好,不然代码量一大,局部的重命名全局都没注意到
dir方向数组搞反了,上下左右对应于二维数组的话,上是减x而不是y
处理多组数据需要初始化状态数据
//使用memset的几个细节 int vis[10]; memset(vis, -1, sizeof(vis));//使用memset不仅可以初始化为0,还可以是-1 int vis[10]; fill(vis, 44, sizeof(vis));//fill与memset的区别,fill是直接填充数据,而memset是填充字节,所以fill可以初始化认值数字 bool vis[10]; memset(vis, -1, sizeof(vis)); printf("%d", vis[0]);//输出255, 因为memset填充数据 if(vis[0] == 255) printf("yes\n");//输出yes,所以要注意初始化类型,bool到不到预期,要使用int if(vis[0] == 1) printf("no\");
思路与总结
- 对于隐式的搜索要能够识别出来,如果一个问题没办法很好的贪心,dp或者数学之类的方法,可以考虑一下暴力+搜索,画出每个的状态转移,分析一下时间复杂度,没准就可以轻松的解出来,而不需要去想那么复杂
- 要掌握好基本功,以下几个变形都是在熟悉bfs的基础上有所变化,如果对基本的操作都不熟练,很难对以下几个变形掌握和临场发挥
- bfs的几个变种
- 多源bfs(对应的隐式图要能够识别到,学会将问题转化为多源bfs)
- bfs使用优先队列解最优解(注意结构体的优先级定义以及priority_queue)
- 注意状态转移
- bfs的做题步骤思路
- 能不能够使用暴力+搜索的方式进行处理,找到对应的状态,如果能够转化为对应的搜索树
- 分析时间复杂度,是否可行,还是需要优化
- 答案对最优解是什么,定义结构体和优先级
- 搜索的状态转移分析清晰
题号
PIPIOJ 1110 (显式图简单BFS)
PIPIOJ 1024 (隐式图搜索)
PIPIOJ 1098 (隐式图搜索)
PIPIOJ 1032 (多源BFS)
PIPIOJ 1169 (优先队列的使用)
PIPIOJ 1101 (多源+优先队列+多次BFS)
PIPIOJ 1027 (直接搜索版本)
PIPIOJ 1027 (优先队列版本)
PIPIOJ 1211 (多源BFS)
PIPIOJ 1100 (作业)
分析
1024
- 隐式图,需要分析状态,对应每个状态为1, -1, *2,因此可以简单化很多,而不是去找规律贪心做
1032
- 多源bfs
1169
隐式图,分析出每次的状态,直接暴力搜索
状态数据使用二维就ok了
配合优先队列最快找出最优解,以下结构体用来配合优先队列
//结构体的几种用法 //几个注意点 //1.优先级是定义小于号的话,应该是true表示小 //2.写法,2个const,同时注意地址符号 struct Node{ int x, y; bool operator < (const Node &node) const{ return y > node.y; } } 结构体的初始化技巧 queue<Node> Q; Q.push({1, 2});
每次搜索后维护解空间
1101
- 多源bfs(识别隐式图)
- 将主函数拆开写,逻辑更加清楚,好debug
- 初始化很重要,可能特殊清空下,直接使用初始化数组,我这题初始化为-1,直接导致一种特殊清空无法处理,找了半天
1027
- 判断地址合法除了越界,还要判断障碍物
- 配合优先队列找最优解
- 同时找最优解,还要在状态转移上有所变化,这题bfs不是一个点只招最近4个方向的点,还要考量转弯,所以在方向转移时,是一条路径上的点都要计入这次的状态转移,然后使用优先队列进行找解
1211
- 这题基本功太差,以为就是简单的bfs,就写了半天,结果超时,不够熟练
- 这题需要分析一下时间复杂度,如果直接bfs,时间复杂度是n*(n + m),n最大1e5,会超时
- 转为对货物进行多源bfs,将问题简化,同时也转化为多源bfs,大大简化时间复杂度
1100
- 二维数组的上下左右搞错了
- 配合优先队列,追求最短时间
- 状态转移要分析记录一下,不同的梯子状态转移不同
标签:记录,队列,bfs,vis,搜索,PIPIOJ,机试,第六次,多源 来源: https://www.cnblogs.com/faberry/p/12391598.html