题目来源:

题库 - AcWing

目录

DFS和BFS模板题目:迷宫类

机器人的运动范围​

字母

迷宫

红与黑

棋盘问题

马走日

全球变暖

DFS综合类

乘积最大(提高课)

单词接龙(提高课)

取石子游戏(dfs数学推理)


机器人的运动范围

 BFS:

class Solution {
public:int get_sum(pair<int, int> p) {int s = 0;while (p.first) {s += p.first % 10;p.first /= 10;}while (p.second) {s += p.second % 10;p.second /= 10;}return s;}int movingCount(int threshold, int rows, int cols){if (!rows || !cols) return 0;queue<pair<int,int>> q;vector<vector<bool>> st(rows, vector<bool>(cols, false));int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};int res = 0;q.push({0, 0});while (q.size()) {auto t = q.front();q.pop();if (st[t.first][t.second] || get_sum(t) > threshold) continue;res ++ ;st[t.first][t.second] = true;for (int i = 0; i < 4; i ++ ) {int x = t.first + dx[i], y = t.second + dy[i];if (x >= 0 && x < rows && y >= 0 && y < cols) q.push({x, y});}}return res;}
};

DFS:

class Solution {
public:
int k;
int b,a;
int f[52][52];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};int movingCount(int threshold, int rows, int cols){memset(f,false,sizeof f);b=cols,a=rows;int res=0;k=threshold;return    dfs(0,0);}int dfs(int y,int x){if(x<0||x>=a||y<0||y>=b||f[y][x]) return 0;f[y][x]=true;int res=0;int x1=x,y1=y;while(x1){res+=(x1%10);x1/=10;}while(y1){res+=(y1%10);y1/=10;}if(res>k) return 0;int sum=0;for(int i=0;i<4;i++){int q=x+dx[i],p=y+dy[i];sum+=dfs(p,q);}return sum+1;}
};作者:dfbdberberb
链接:https://www.acwing.com/solution/content/11722/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

乘积最大(较难)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;int n, k, ans;
string str;
bool st[20];//标记数字是否出现过
vector<int>num;//存放分割的数字int number(int l, int r)//求区间[l,r]的数字
{int res = 0;for (int i = l; i <= r; i++)res = res * 10 + str[i] - '0';return res;
}void dfs(int pos, int cnt)//枚举到的第几个空位,乘号的当前个数
{if (cnt == k)//如果乘号个数==题目所给的乘号个数{int y = number(pos, n - 1);//求出分割k次以后,第k+1个数的大小num.push_back(y);//放入分割的数字中int tmp = 1;for (int i = 0; i < num.size(); i++)//求乘积tmp *= num[i];//          cout<<num[i]<<" ";//      cout<<endl;ans = max(ans, tmp);//更新最大值num.pop_back();return;}for (int i = 0; i < n - 1; i++)//枚举分割位置{if (!st[i] && pos <= i)//如果分割位置未出现过,向下搜索{int x = number(pos, i);num.push_back(x);st[i] = true;dfs(i + 1, cnt + 1);st[i] = false;num.pop_back();}}
}int main()
{cin >> n >> k;cin >> str;dfs(0, 0);cout << ans << endl;return 0;
}

字母

 BFS:

需要额外开一个字母数组来哈希快速找到该字母是否之前已经走过

#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<memory.h>
#include<cstring>
using namespace std;int n, m;
const int N = 50;
vector<string> V;
int mp[26];struct STATE {int x, y;int mp[26];int step;
};int ans = -1;
int addx[4] = { 1,-1,0,0 };
int addy[4] = { 0,0,-1,1 };void bfs()
{queue<struct STATE> q;struct STATE s;memset(s.mp, 0, sizeof s.mp);s.mp[V[0][0] - 'A'] = 1;//标记s.step = 1;s.x = 0, s.y = 0;q.push(s);while (q.size()){auto t = q.front();q.pop();ans = max(ans, t.step);for (int i = 0; i < 4; i++){int newx = t.x + addx[i];int newy = t.y + addy[i];if (newx >= 0 && newx < n && newy >= 0 && newy < m){int idx = V[newx][newy] - 'A';if (t.mp[idx] == 1) continue;struct STATE next;next.x = newx;next.y = newy;next.step = t.step + 1;memcpy(next.mp, t.mp, sizeof t.mp);next.mp[idx] = 1;q.push(next);}}}
}int main()
{cin >> n >> m;for (int i = 0; i < n; i++){string s;cin >> s;V.push_back(s);}bfs();cout << ans << endl;return 0;
}

DFS:

同样需要开一个字母数组,来判断该字母是否出现过

不同的地方在与DFS搜索迷宫具有对称性:标记(   )搜索下一层(  )取消标记

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;int n, m;
const int N = 50;
vector<string> V;
int mp[26];
int ans = -1;int addx[] = { 1,-1,0,0 };
int addy[] = { 0,0,-1,1 };void dfs(int x, int y, int step)
{int idx = V[0][0] - 'A';mp[idx] = 1;for (int i = 0; i < 4; i++){int newx = x + addx[i];int newy = y + addy[i];if (newx >= 0 && newx < n && newy >= 0 && newy < m){int idx = V[newx][newy] - 'A';if (mp[idx] == 1) continue;mp[idx] = 1;dfs(newx, newy, step + 1);mp[idx] = 0;}}ans=max(ans,step);
}int main()
{cin >> n >> m;for (int i = 0; i < n; i++){string s;cin >> s;V.push_back(s);}dfs(0, 0, 1);cout << ans << endl;return 0;
}

迷宫

 BFS:

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;typedef pair<int, int> PII;
const int N = 110;
int n;
char g[N][N];
bool st[N][N];
queue<PII> q;
int startx, starty;
int endx, endy;int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };void bfs()
{q.push({ startx,starty });st[startx][starty]=true;while (q.size()){auto t = q.front();q.pop();for (int i = 0; i < 4; i++){int x = t.first + dx[i];int y = t.second + dy[i];if (x >= 0 && x < n && y>=0 && y < n && !st[x][y] && g[x][y] == '.'){st[x][y] = true;q.push({ x,y });}else continue;}}
}int main()
{int T;cin >> T;while (T--){cin >> n;for (int i = 0; i < n; i++) cin >> g[i];cin >> startx >> starty;cin >> endx >> endy;bfs();if(g[startx][starty]=='#' || g[endx][endy]=='#' || !st[endx][endy])cout << "NO" << endl;else if (st[endx][endy]) cout << "YES" << endl;memset(st, false, sizeof st);}return 0;
}

DFS:

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 110;char g[N][N];
bool st[N][N];
int n;
int l1, r1, l2, r2;
int dx[] = {0, -1, 0, 1}, dy[] = {-1, 0, 1, 0};
bool dfs(int x, int y)
{if(x == l2 && y == r2)return true;st[x][y] = true;for(int i = 0; i < 4; i ++){int a = x + dx[i], b = y + dy[i];if(a < 0 || a >= n || b < 0 || b >= n)continue;if(g[a][b] == '#')continue;if(st[a][b])continue;if(dfs(a, b))return true;}return false;
}int main()
{int T;cin >> T;while(T --){memset(st, false, sizeof st);cin >> n;for(int i = 0; i < n; i ++) cin >> g[i];cin >> l1 >> r1 >> l2 >> r2;if(g[l1][r1] == '#' || g[l2][r2] == '#'){puts("NO");continue;}if(dfs(l1, r1))puts("YES");else puts("NO");}return 0;
}

红与黑

 DFS:

#include<iostream>
#include<cstring>
using namespace std;
const int N=25;
char g[N][N];
bool st[N][N];
int n,m;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};int dfs(int x,int y)
{int cnt=1;st[x][y]=true;for(int i=0;i<4;i++){int a=x+dx[i];int b=y+dy[i];if(a<0 || a>=n || b<0 || b>=m) continue;if(g[a][b]!='.') continue;if(st[a][b]) continue;cnt+=dfs(a,b);}return cnt;
}int main()
{while (cin >> m >> n, n || m){for (int i = 0; i < n; i++) cin >> g[i];int x, y;for(int i=0;i<n;i++)for (int j = 0; j < m; j++){if (g[i][j] == '@'){x = i;y = j;}}memset(st, 0, sizeof st);cout << dfs(x, y) << endl;}return 0;
}

棋盘问题

//DFS
//类似于八皇后的一道多了一些限制的题#include <cstdio>
#include <iostream>
#include <cstring>using namespace std;const int N = 20;char g[N][N];                                       //存储输入棋盘
int ans;                                            //存储答案
int n, k;
int m;                                              //存储已近放入棋盘的棋子数
bool line[N];                                       //存储当前列上有没有其他棋子 void dfs(int x)
{if(m == k)                                      //当棋子放光的时候 {ans++;return;}if(x == n)                                      //防止越界 return;dfs(x + 1);     //这个是关键,因为 k <= m,因此可能有行不用放棋子,所以我们要手动舍弃行,直接进入下一行 for(int i = 0; i < n; i++)                      //爆搜 if(!line[i] && g[x][i] == '#'){line[i] = true;m++;                                    //记录放入的棋子数 dfs(x + 1);line[i] = false;                        //还原初始状态 m--;}}int main()
{while(scanf("%d%d", &n, &k) && n != -1 && k != -1){ans = m = 0;for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)cin >> g[i][j];dfs(0);cout << ans << endl;}return 0;
}

取石子游戏

#include<iostream>
#include<algorithm>
using namespace std;int n, m;void dfs(int a, int b, int step)
{if (a % b == 0 || a / b >= 2){if (step & 1){cout << "win" << endl;return;}else{cout << "lose" << endl;return;}}dfs(b, a % b, step + 1);
}int main()
{while (cin >> n >> m, n || m){if (n < m) swap(n, m);if (n / m >= 2) cout << "win" << endl;else dfs(n, m, 1);}return 0;
}

马走日

#include<bits/stdc++.h>
using namespace std;
int T,n,m,a,b,ans;
int vis[20][20];
int dx[8]={2,1,-1,-2,-2,-1,1,2};//方向数组
int dy[8]={1,2,2,1,-1,-2,-2,-1};//方向数组
void dfs(int x,int y,int step)//step记录当前走了几个格子
{if(step==n*m){//已遍历完所有的格子ans++;//答案加一return;}for(int i=0;i<8;i++){int kx=x+dx[i];int ky=y+dy[i];if(kx>=0&&kx<n&&ky>=0&&ky<m&&vis[kx][ky]==0){//判断vis[kx][ky]=1;//标记dfs(kx,ky,step+1);vis[kx][ky]=0;//回溯}}
}
int main()
{scanf("%d",&T);while(T--){//多组测试数据ans=0;//一定要记得清空数据memset(vis,0,sizeof(vis));scanf("%d %d %d %d",&n,&m,&a,&b);vis[a][b]=1;//标记起点dfs(a,b,1);printf("%d\n",ans);}return 0;
}

单词接龙(提高课)

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 21;int n;
string word[N];
int g[N][N];//代表编号i的可以被j拼接  如i:asd,j:sdf,拼接长度为最小值g[i][j] = 2,i从0开始记位
int used[N];//编号为i的单词使用次数
int ans;void dfs(string dragon, int last)
{ans = max((int)dragon.size(), ans);//取最大值,dragon.size()为当前合并的长度used[last]++;//编号为last的单词被用次数++;for (int i = 0; i < n; i++)if (g[last][i] && used[i] < 2)//used[i]<2代表单词用次数不超过2dfs(dragon + word[i].substr(g[last][i]), i); //编号为last的可以被i拼接现在尾巴为i号used[last]--;//恢复现场
}int main() {cin >> n;for (int i = 0; i < n; i++) cin >> word[i];char start;cin >> start;//首字母for (int i = 0; i < n; i++)//遍历得到各个g[i][j]for (int j = 0; j < n; j++) {string a = word[i], b = word[j];for (int k = 1; k < min(a.size(), b.size()); k++)if (a.substr(a.size() - k, k) == b.substr(0, k)) {g[i][j] = k;break;}}for (int i = 0; i < n; i++)//找到首字母为strat的单词开始做dfs,dfs中会自动找到最大值if (word[i][0] == start)dfs(word[i], i);//从word[i]开始遍历,i代表现在是第几个单词cout << ans << endl;return 0;
}

全球变暖

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
// total : 岛屿的板块的数量  bound:邻接海洋的岛屿板块的数量
void bfs(int sx, int sy, int& total, int& bound)
{int hh = 0;int tt = 0;q[0] = { sx,sy };st[sx][sy] = true;while (hh <= tt){PII t = q[hh++];total++;bool is_bound = false;for (int i = 0; i < 4; i++){int x = t.x + dx[i];int y = t.y + dy[i];if (x < 0 || x >= n || y < 0 || y >= n) continue;if (st[x][y]) continue;//如果已经走过了if (g[x][y] == '.')//上下左右之中有一个为海{is_bound = true;continue;}q[++tt] = { x,y };st[x][y] = true;}if (is_bound) bound++;//只要上下左右之中有一个为海,那么它就是边界}
}int main()
{cin >> n;for (int i = 0; i < n; i++) cin >> g[i];int cnt = 0;for(int i=0;i<n;i++)for(int j=0;j<n;j++)if (!st[i][j] && g[i][j] == '#'){int total = 0;int bound = 0;bfs(i, j, total, bound);if (total == bound) cnt++;}cout << cnt << endl;return 0;
}

[AcWing算法刷题]之DFS+BFS迷宫模板(简单)相关推荐

  1. 算法刷题7(C++)BFS算法

    一.算法概述 BFS算法本质就是从起点到终点找到最近的距离. BFS算法核心把一个问题抽象成图,从一个点开始,向四周开始扩散. 比DFS的空间复杂度大. 二.算法框架 int BFS(Node sta ...

  2. 深度优先搜索dfs算法刷题笔记【蓝桥杯】

    其实网上已经有不少dfs的算法笔记,但我之所以还再写一篇,主要是因为我目前见到的笔记,都有些太偏向理论了. 对于基础薄弱的或是没有基础的人(like me),有点不合适,因为看了,也不能说自己会了. ...

  3. 【c++算法刷题笔记】——洛谷2

    1. 洛谷练习--P1579 哥德巴赫猜想(升级版) 题目描述: 现在请你编一个程序验证哥德巴赫猜想. 先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数. 输入格式: 仅有一行,包含一 ...

  4. 找到所有数组中消失的数字_【一点资讯】千万程序员的呼声:面试如何拿到大厂Offer?这份阅读量超过11W+的算法刷题宝典请你原地查收 www.yidianzixun.com...

    如何才能通过面试拿到大厂Offer? "刷leetcode!" 这是我听到最多的回答! 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是面测试.算 ...

  5. 搬砖试金石!github星标7W算法刷题宝典,还愁拿不下大厂offer?

    前言 这几年IT技术蓬勃发展,日新月异,对技术人才的需求日益增长,程序员招聘市场也如火如荼.在有限的三五轮面试中,国外流行让面试者编程解决某些数据结构和算法的题目,通过观察面试者编码的熟练程度.思考的 ...

  6. 算法刷题系列(四)蓝桥杯python算法训练3(下)

    上一次的节点选择算法由于春节过年耽搁了,现在重新补上 上篇链接:算法刷题系列(四)蓝桥杯python算法训练3 - 经验教训 在纷繁复杂的使用了列表来暂存数据之后,发现其实可以利用笔者自己不太常用的字 ...

  7. 字节跳动算法刷题宝典.pdf

    今天推荐一个关于「算法刷题宝典」的开源项目:力扣Cookbook. 力扣 Cookbook是@halfrost(中文名:霜神)去年刷的 力扣整理出的 520 题,每道题都写了解题思路,并且每题都 ru ...

  8. Github最强算法刷题笔记.pdf

    资料一 昨晚逛GitHub,无意中看到一位大佬(https://github.com/halfrost)的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙 ...

  9. 算法刷题宝典.pdf

    今天推荐一个关于「算法刷题宝典」的开源项目:力扣Cookbook. 力扣 Cookbook是@halfrost(中文名:霜神)去年刷的 力扣整理出的 520 题,每道题都写了解题思路,并且每题都 ru ...

最新文章

  1. CentOS安装中文输入法
  2. 耗时 2 年,用 8.5 万块乐高积木最牛复刻 Apple Park
  3. cstring转为long64_CString 与其他数据类型的转换(转)
  4. Linux各发行版本之间的比较
  5. 易创互联 php,易创网站管理系统(DIRCMS) 2011 SP3 UTF8
  6. js 通过jquery插件获取url参数 其中的一个小问题,或许不算Bug。
  7. 【问题解决】无法创建新的堆栈防护页面
  8. BGP 路由表即将突破 768k
  9. linux修正磁盘错误,找到了linux分区顺序错乱修复方法
  10. SpringCloud工作笔记041---com.fasterxml.jackson.databind.ObjectMapper的使用
  11. mysql ignore caps_mysql优化之sql语句优化
  12. webstorm使用插件 statistic 统计代码
  13. k8s使用kube-router网络插件并监控流量状态 1
  14. 信用评分卡模型分析(基于Python)--理论部分
  15. Udacity也弃用React Native了 !
  16. 网络编程在线英英词典之注册模块实现(三)
  17. 前端7大常用布局方式
  18. 计算机java证书有哪些_计算机专业应该考这些证书!
  19. innodb system table
  20. 六下计算机教学总结,六年级下册信息技术教学工作总结

热门文章

  1. Linux 快照 (snapshot) 原理与实践(一) 快照基本原理
  2. 联系电脑清除BIOS密码方法
  3. 渗透测试之文件包含[汇总]
  4. 红帽系统实现基础网站框架搭建
  5. 开放平台:新浪微博 for iOS
  6. Python程序员:8个接私活的网站,只要你有码,那“我”就有钱
  7. IT软件人才驻场开发的费用怎么算?
  8. 什么叫电阻和电阻率?什么叫电导和电导率?
  9. activiti 网页流程设计器 的使用
  10. shell 脚本参数$10