第四章:搜索

深搜

深搜是一种用到递归的思想,是优雅的暴力。
深搜实现全排列:

#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 105;
int a[maxn] = {0};
bool visited[maxn];
int n;
void solve(int step){if(step == n+1){for(int i=1;i<=n;i++){cout<<a[i]<<' ';}cout<<endl;return;}for(int i=1;i<=n;i++){if(!visited[i]){visited[i] = true;a[step] = i;
//          if(step == n) cout<<i<<' ';solve(step+1);visited[i] = false;}}
}
int main(){cin>>n;
//  for(int i=1;i<=n;i++){//      a[i] = i;
//  }memset(visited,false,sizeof(visited));solve(1);return 0;
}

输出项即有n!个。

深搜实现迷宫:从(1,1)前往(n,m),其中1是障碍,0可通行。

#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 105;
int s[maxn][maxn] = {0},res = 1e5+5;
bool visited[maxn][maxn];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int n,m;
void solve(int x,int y,int step){if(x == n && y == m){res = min(res,step);return;}if(step >= res)  return;for(int i=0;i<4;i++){int nx = x + dx[i],ny = y + dy[i];if(!visited[nx][ny] && nx >= 1 && ny >= 1 &&nx <= n && ny <= m && !s[nx][ny]){visited[nx][ny] = true;solve(nx,ny,step+1);visited[nx][ny] = false;}}
}int main()
{cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>s[i][j];}}memset(visited,false,sizeof(visited));solve(1,1,0);cout<<res;return 0;
}

广搜

广搜即用队列实现的搜索方式。顾名思义,深搜在于深度,广搜在于广度。
广搜实现马的遍历:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 405;
int s[maxn][maxn] = {0};
bool visited[maxn][maxn];
struct xy{int x,y;xy(int tx,int ty){x = tx;y = ty;}
};
queue<xy> q;
int n,m,x,y;
int dx[] = {1,1,-1,-1,2,2,-2,-2};
int dy[] = {-2,2,-2,2,-1,1,-1,1};
void solve(){xy f(x,y);visited[x][y] = true;q.push(f);while(!q.empty()){       //能进入队列的一定是已经遍历过的点。 xy p = q.front();q.pop();for(int i=0;i<8;i++){int nx = p.x + dx[i],ny = p.y + dy[i],ns = s[p.x][p.y] + 1;if(nx >= 1 && nx <= n && ny >= 1 && ny <= m &&!visited[nx][ny]){xy t(nx,ny);visited[nx][ny] = true;s[nx][ny] = ns;q.push(t);}}}
}
int main()
{cin>>n>>m>>x>>y;memset(visited,false,sizeof(visited));solve();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(s[i][j] || (i == x && j == y)){printf("%-5d",s[i][j]);}else{printf("%-5d",-1);}}cout<<endl;}return 0;
}

广搜实现FloodFill:

#include<iostream>
#include<cstring>
#include <string>
#include <queue>
using namespace std;
const int maxn = 1005;
struct xy{int x,y;xy(int tx,int ty){x = tx;y = ty;}
};
queue<xy> q;
char s[maxn][maxn];
bool visited[maxn][maxn];
int n,m,res = 0;
int dx[] = {0,0,1,-1,1,1,-1,-1};
int dy[] = {1,-1,0,0,1,-1,1,-1};
void solve(int x,int y){visited[x][y] = true;xy f(x,y);q.push(f);while(!q.empty()){xy p = q.front();q.pop();for(int i=0;i<8;i++){int nx = p.x + dx[i],ny = p.y + dy[i];if(!visited[nx][ny] && nx >= 1 && nx <= n &&ny >= 1 && ny <= m && s[nx][ny] != '.'){visited[nx][ny] = true;xy t(nx,ny);q.push(t);}}}
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>s[i][j];}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cout<<s[i][j];}cout<<endl;}memset(visited,false,sizeof(visited));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(!visited[i][j] && s[i][j] == 'W'){solve(i,j);res ++;}}}cout<<res<<endl;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(visited[i]){cout<<1<<' ';}else{cout<<0<<' ';}}cout<<endl;}return 0;
}

其他

显然上述的代码只是非常基础的搜索模板。由于搜索是一种思想,故它的模板可变,随题意而更改。
除了深搜和广搜之外,还有记忆化搜索(接近于动态规划),双向dfs,启发式搜索,剪枝策略等。

啊哈算法——第四章:搜索相关推荐

  1. 斗地主AI算法——第四章の权值定义

    第一章业务逻辑结尾部分我提到了权值的计算方法: ①每个单牌都有一个基础价值②组合牌型的整体价值与这个基础价值有关,但显然计算规则不完全一样.③整手牌可以分成若干个组合牌,但分法不唯一. 当时,我说了① ...

  2. 啊哈算法第四章 万能的搜索

    从这一章开始就真的步入对我而言全新的算法世界了(因为排序.枚举在上学期还是接触过的,而栈.队列在这学期我看的C++Primer和老师教的Java课里也有所涉及) 一.深度优先搜索(Depth Firs ...

  3. 斗地主AI算法——第三章の数据处理

    上一章我们定义了基本的数据结构,相信大家看到手牌类里面那么多出牌序列时一定会比较愤慨... 其实一开始写的时候我也是觉得很脑残,不过后续开发证明了这样的结构还是可以的,因为只要我封装了一层数据转换,接 ...

  4. 《啊哈算法》第四章 万能的搜索

    参考:<啊哈算法> 这里的搜索与图的遍历要区分开,这里只是对数的搜索进行尝试,常用于地图搜索什么,查找是否通路什么的. 深度优先搜索 问题 求出数字123的全排列 额,先来暴力一个: #i ...

  5. AcWing提高算法课Level-3 第四章 高级数据结构

    AcWing提高算法课Level-3 第四章 高级数据结构 并查集 AcWing 1250. 格子游戏1167人打卡 AcWing 1252. 搭配购买1064人打卡 AcWing 237. 程序自动 ...

  6. 算法与数据结构 第四章 树与二叉树

    第四章树 一.选择题(20分) 1.在下述结论中,正确的是: (    ) ① 只有2个结点的树的度为1: ② 二叉树的度为2: ③ 二叉树的左右子树可任意交换: ④ 在最大堆(大顶堆)中,从根到任意 ...

  7. c语言实现bf算法的定位函数,数据结构c语言版严蔚敏清华大学出版社第四章串.ppt...

    数据结构c语言版严蔚敏清华大学出版社第四章串 模式匹配(定位) 设有主串S和子串T(将S称为目标串,将T称为模式串),在主串S中,从位置start开始查找,如若在主串S中找到一个与子串T相等的子串,则 ...

  8. 算法复习第四章动态规划

    算法复习第四章动态规划 动态规划 TSP问题 0-1bag 动态规划 TSP问题 0-1bag 最长公共子序列不考:

  9. AcWing进阶算法课Level-4 第六章 搜索 (模拟退火,爬山)

    AcWing进阶算法课Level-4 第六章 搜索 模拟退火 AcWing 3167. 星星还是树110人打卡 AcWing 2424. 保龄球78人打卡 AcWing 2680. 均分数据72人打卡 ...

最新文章

  1. 高速缓冲DNS相关配置详情
  2. html实战例子: 点击图片超链接跳转
  3. 程序组件通信方案集锦
  4. 贝叶斯、先验估计、后验估计、最大似然估计、最大后验估计
  5. java double 小数点后两位小数_Java中double类型的数据精确到小数点后两位
  6. EditText 被遮挡和显示不全问题
  7. EFCore动态切换Schema
  8. java虚拟机和javaGC_Java虚拟机(三):GC算法和种类
  9. 电脑练习打字软件_练习打字软件Master of Typing 3 Mac
  10. CV Code | 计算机视觉开源周报 20190603期
  11. JavaScript 获取当日在今年第几周
  12. java中常见数据库字段类型与java.sql.Types的对应
  13. [Perl系列二-实战] 1. Perl 读取代码的行数
  14. 【JavaScript】创建对象的三种方式
  15. SASS用法指南(转)
  16. sublime批量添加注释
  17. Linux下conda安装caffe(超简单),pb转caffe
  18. c语言函数任意个数参数的实现
  19. CAD调整十字光标的长度
  20. 计算机房灭火器单具基准,灭火器配置数量的参考

热门文章

  1. quartz学习 图灵
  2. appium自动化之对手机按键的操作
  3. Dev C++详细安装教程及软件下载
  4. Qt 错误 The process was ended forcefully.
  5. 前端代码深浅拷贝四种方式
  6. quickpcb添加pcb库_QuickPcb2005元件库(QuickPcb集成元件库)V1.0 最新版
  7. open-falcon详解
  8. hadoop与java中数据类型转换
  9. 命令行执行sql脚本
  10. 在艳遇的6个小时里,我们都说了啥?