DFS/BFS专训2

文章目录

  • DFS/BFS专训2
    • A. 面积
    • B. 营救
    • C. 最少转弯问题
    • D. 麻将游戏
    • E. 门票问题
    • F. 奇怪的电梯(lift)

A. 面积

题目描述
编程计算由“ * ”号围成的下列图形的面积。面积计算方法是统计*号所围成的闭合曲线中水平线和垂 直线交点的数目。如下图所示,在 10 * 10 的二维数组中,有“ * ”围住了 15 个点,因此面积为 15。

0 0 0 0 0 0 0 0 0 0
0 0 0 0 * * * 0 0 0
0 0 0 0 * 0 0 * 0 0
0 0 0 0 0 * 0 0 * 0
0 0 * 0 0 0 * 0 * 0
0 * 0 * 0 * 0 0 * 0
0 * 0 0 * * 0 * * 0
0 0 * 0 0 0 0 * 0 0
0 0 0 * * * * * 0 0
0 0 0 0 0 0 0 0 0 0

输入格式 一个矩阵

输出格式 面积

样例输入

0 0 0 0 0 0 0 0 0 0
0 0 0 0 * * * 0 0 0
0 0 0 0 * 0 0 * 0 0
0 0 0 0 0 * 0 0 * 0
0 0 * 0 0 0 * 0 * 0
0 * 0 * 0 * 0 0 * 0
0 * 0 0 * * 0 * * 0
0 0 * 0 0 0 0 * 0 0
0 0 0 * * * * * 0 0
0 0 0 0 0 0 0 0 0 0

样例输出

15

代码
从四边向内进行宽搜 再用总面积减去未被围起来的面积即可

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;int a[50][50];
bool v[50][50];
int n = 10, cnt;
char c;
int dx[4] = { 0, 1, 0, -1 };
int dy[4] = { 1, 0, -1, 0 };struct node {int x;int y;
};
queue<node> q;void bfs() {while (!q.empty()) {node f = q.front();q.pop();for (int i = 0; i < 4; i++) {node t;t.x = f.x + dx[i];t.y = f.y + dy[i];if (t.x >= 1 && t.x <= n && t.y >= 1 && t.y <= n && !a[t.x][t.y] && !v[t.x][t.y]) {v[t.x][t.y] = 1;a[t.x][t.y] = 1;q.push(t);}}}
}int main() {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {scanf("%d", &a[i][j]);}}for (int i = 1; i <= n; i++) {if (a[1][i] == 0) {a[1][i] = 1;v[1][i] = 1;q.push({ 1, i });break;}}for (int i = 1; i <= n; i++) {if (a[i][10] == 0) {a[i][10] = 1;v[i][10] = 1;q.push({ i, 10 });break;}}for (int i = 1; i <= n; i++) {if (a[i][1] == 0) {a[i][1] = 1;v[i][1] = 1;q.push({ i, 1 });break;}}for (int i = 1; i <= n; i++) {if (a[10][i] == 0) {a[10][i] = 1;v[10][i] = 1;q.push({ 10, i });break;}}bfs();for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if (a[i][j] == 0)cnt++;}}printf("%d", cnt);
}

B. 营救

题目描述
铁塔尼号遇险了!他发出了求救信号。距离最近的哥伦比亚号收到了讯息,时间就是生命,必须尽快 赶到那里。
通过侦测,哥伦比亚号获取了一张海洋图。这张图将海洋部分分化成 n*n 个比较小的单位,其中用 1 标明的是陆地,用 0 标明是海洋。船只能从一个格子,移到相邻的四个格子。
为了尽快赶到出事地点,哥伦比亚号最少需要走多远的距离。

输入格式
第一行为 n,下面是一个 n*n 的 0、1 矩阵,表示海洋地图。
最后一行为四个小于 n 的整数,分别表示哥伦比亚号和铁塔尼号的位置。

输出格式
哥伦比亚号到铁塔尼号的最短距离,答案精确到整数。

样例输入

3
001
101
100
1 1 3 3

样例输出

4

代码
宽搜水题

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;struct node {int x, y, dis;
};
queue<node> q;
int n, stx, sty, edx, edy;
string s;
int a[1010][1010], ans[1010][1010];
bool v[1010][1010];
int dx[4] = { 0, 1, 0, -1 };
int dy[4] = { 1, 0, -1, 0 };void bfs(int x, int y) {while (!q.empty()) {node f = q.front();q.pop();for (int i = 0; i < 4; i++) {node t;t.x = f.x + dx[i];t.y = f.y + dy[i];if (t.x > 0 && t.y > 0 && t.x <= n && t.y <= n && a[t.x][t.y] == 0 && v[t.x][t.y] == 0) {//    printf("%d %d\n",t.x ,t.y);v[t.x][t.y] = 1;t.dis = f.dis + 1;ans[t.x][t.y] = t.dis;q.push(t);if (t.x == edx && t.y == edy) {printf("%d\n", t.dis);break;}}}}
}int main() {scanf("%d", &n);for (int i = 1; i <= n; i++) {cin >> s;for (int j = 1; j <= n; j++) {a[i][j] = s[j - 1] - '0';}}scanf("%d%d%d%d", &stx, &sty, &edx, &edy);node st;st.x = stx;st.y = sty;st.dis = 0;v[stx][sty] = 1;q.push(st);bfs(stx, sty);//  for(int i=1;i<=n;i++){//     for(int j=1;j<=n;j++){//         printf("%d ",ans[i][j]);//        }printf("\n");//  }
}

C. 最少转弯问题

题目描述
给出一张地图,这张地图被分为n×m(n,m<=100)个方块,任何一个方块不是平地就是高山。平地可以通过,高山则不能。现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能到达目的地(x2,y2)?你只能沿着水平和垂直方向的平地上行进,拐弯次数就等于行进方向的改变(从水平到垂直或从垂直到水平)的次数。例如:如图,最少的拐弯次数为5。

输入格式

第一行:n和m。
第二至n+1行:一个矩阵,为地图。(0:空地;1:高山。)
第n+2行:x1,y1,x2和y2。

输出格式

只有一行,为最少的转弯次数。

样例输入

5 7
1 0 0 0 0 1 0
0 0 1 0 1 0 0
0 0 0 0 1 0 1
0 1 1 0 0 0 0
0 0 0 0 1 1 0
1 3 1 7

样例输出

5

代码

#include <iostream>
#include <cstdio>
#include <queue>
#define inf 0x7fffffff
using namespace std;struct node {int x, y, dis, dir;
};
queue<node> q;
int n, m, stx, sty, edx, edy;
int a[1010][1010], ans[1010][1010];
bool v[1010][1010];
int dx[4] = { 0, 1, 0, -1 };
int dy[4] = { 1, 0, -1, 0 };
node st;void bfs() {while (!q.empty()) {node f = q.front();//  printf("%d\n",f.dis );q.pop();for (int i = 0; i < 4; i++) {node t;t.dir = i;t.x = f.x + dx[i];t.y = f.y + dy[i];if (f.x == stx && f.y == sty)f.dir = i;if (t.x > 0 && t.y > 0 && t.x <= n && t.y <= m && a[t.x][t.y] == 0) {//    printf("%d %d\n",t.x ,t.y);t.dis = f.dis;if (t.dir != f.dir)t.dis = f.dis + 1;ans[t.x][t.y] = min(ans[t.x][t.y], t.dis);if (v[t.x][t.y] == 0) {v[t.x][t.y] = 1;q.push(t);}}}}
}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {scanf("%d", &a[i][j]);if (a[i][j] == 0)ans[i][j] = inf;}}scanf("%d%d%d%d", &stx, &sty, &edx, &edy);st.x = stx;st.y = sty;st.dis = 0;st.dir = 0;v[stx][sty] = 1;ans[stx][sty] = 0;q.push(st);bfs();//    for(int i=1;i<=n;i++){//     for(int j=1;j<=m;j++){//         printf("%d ",ans[i][j]);//        }printf("\n");//  }printf("%d", ans[edx][edy]);
}

D. 麻将游戏

题目描述 (此题巨坑无比
在一种“麻将”游戏中,游戏是在一个有w*h格子的矩形平板上进行的。每个格子可以放置一个麻将牌,也可以不放(如图所示)。玩家的目标是将平板上的所有可通过一条路径相连的两张相同的麻将牌,从平板上移去。最后如果能将所有牌移除平板,则算过关。

这个游戏中的一个关键问题是:两张牌之间是否可以被一条路径所链接,该路径满足以下两个特性:
(1)它由若干条线段组成,每条线段要么是水平方向,要么是垂直方向。
(2)这条路径不能横穿任何一个麻将牌(但允许路径暂时离开平板)
这是一个例子:

在(1,3)的牌和在(4,4)的牌可以被连接。(2,3)和(3,4)不能被连接。
你的任务是编一个程序,检测两张牌是否能被一条符合以上规定的路径所连接。

输入格式
第一行有两个整数w,h(1<=w,h<=75),表示平板的宽和高。接下来h行描述平板信息,每行包含w个字符,如果某个格子有一张牌,则这个格子上有个’X’,否则是一个空格。平板上最左上角格子的坐标为(1,1),最右下角格子的坐标为(w,h)。接下来的若干行,每行有四个数x1,y1,x2,y2,且满足1<=x1,x2<=w,1<=y1,y2<=h,表示两张牌的坐标(这两张牌的坐标总是不同的)。如果出现连续四个0,则表示输入结束。

输出格式
对于每一对牌输出占一行,为连接这一对牌的路径最少包含的线段数。如果不存在路径则输出0。

样例输入
很坑

5 4
XXXXX
X   X
XXX XXXX
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
//坐标(y,x)

样例输出

4
3
0

代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;int m,n,a[600][600];
string s;
bool v[600][600];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
struct node{int x,y,d;
};
node st,ed;void bfs()
{memset(v,0,sizeof v);queue<node>q;st.d=0;q.push(st);a[ed.x][ed.y]=0;v[st.x ][st.y ]=1;while(!q.empty() ){node f=q.front(); q.pop() ;for(int i=0;i<4;i++){node t;t.x=f.x+dx[i];t.y=f.y+dy[i];while(t.x<=m+1&&t.y<=n+1&&t.x>=0&&t.y>=0&&a[t.x][t.y]==0){//   printf("%d %d %d\n",t.x,t.y,f.d+1);if(t.x==ed.x&&t.y==ed.y){a[ed.x][ed.y]=1; printf("%d\n",f.d+1);return;}if(v[t.x][t.y]==0){v[t.x][t.y]=1;q.push({t.x,t.y,f.d+1}); }t.x+=dx[i];t.y+=dy[i];}} }printf("0\n");a[ed.x][ed.y]=1;
}int main(){//天*的输入!!!! cin>>n>>m;getline(cin,s);for(int i=1;i<=m;i++){getline(cin,s);for(int j=0;j<n;j++)if(s[j]=='X') a[i][j+1]=1;}for(int i=1;;i++){scanf("%d%d%d%d",&st.y ,&st.x ,&ed.y ,&ed.x );//注意xy是反的if(st.x==0) return 0;bfs();}return 0;
}

注意输入!!(字符串总是会出现一些莫名其妙的问题
如果采用

scanf("%d%d\n",&m,&n);
for(int i=1;i<=n;i++{getline( cin, s) ;for(int j=0;j<m;j++)if(s[j]=='X') a[i][j+1]=1;
}

会出事!!!!!!!!!!
例如

5 4XXX
X   X
XXX XXXX

‘ \n ’会滤掉回车键 包括矩阵第一行的空格!
这样读入就变成了

XXX
X   X
XXX XXXX

会出大问题
调了两个小时


E. 门票问题

题目描述
有很多人在门口排队,每个人将会被发到一个有效的通行密码作为门票。一个有效的密码由 L(3≤L≤15)个小写英文字母组成,至少有一个元音(a、e、i、o 或 u)和两个辅音(除去元音以外的音节),并且是按字母表顺序出现的(例如 abc 是有效的,而 bac 不是)。

现在给定一个期望长度为L和C(1≤C≤26)个小写字母,写一个程序,输出所有的长度为L、能由所给定的 C 个字母组成的有效密码。密码必须按字母表顺序打印出来,一行一个。

输入格式
第 1 行是两个由一个空格分开的正整数,L 和 C,3≤L≤15,1≤C≤26。

第 2 行是 C 个由一个空格隔开的小写字母,密码是由这个字母集中的字母来构建的。

输出格式
若干行,每行输出一个长度为 L 个字符的密码(没有空格)。输出行必须按照字母顺序排列。

程序只需要输出前 25 000 个有效密码,即使后面还存在有效密码。

样例输入

4 6
a t c i s w

样例输出

acis
acit
aciw
acst
acsw
actw
aist
aisw
aitw
astw
cist
cisw
citw
istw

代码
半全排列 经典深搜 check比较麻烦

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;int l, c, cnt;
char a[50], t[50];bool check(int k) {for (int i = 1; i < k; i++) {if (t[k] <= t[i])return 0;}return 1;
}bool sieve(char x) {if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u') {return 1;}return 0;
}bool check_f() {int cnt_f = 0, cnt_ff = 0;for (int i = 1; i <= l; i++) {if (sieve(t[i]))cnt_f++;elsecnt_ff++;}if (cnt_f >= 1 && cnt_ff >= 2)return 1;elsereturn 0;
}void dfs(int k) {if (cnt >= 25000)return;if (k == l + 1) {if (check_f() == 0)return;for (int i = 1; i <= l; i++) {printf("%c", t[i]);}printf("\n");cnt++;} else {for (int i = 1; i <= c; i++) {t[k] = a[i];if (check(k)) {dfs(k + 1);}}}
}int main() {scanf("%d%d", &l, &c);for (int i = 1; i <= c; i++) {cin >> a[i];}sort(a + 1, a + 1 + c);dfs(1);
}

F. 奇怪的电梯(lift)

题目描述
大楼的每一层楼都可以停电梯,而且第 i 层楼(1<=i<=N)上有一个数字 Ki(0<=Ki<=N)。 电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果 不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5 代表了 Ki(K1=3,K2=3,……),从一 楼开始。在一楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有-2 楼。那么, 从 A 楼到 B 楼至少要按几次按钮呢?

输入格式
输入文件共有二行,第一行为三个用空格隔开的正整数,表示 N,A,B(1≤N≤200, 1≤ A,B≤N),第二行为 N 个用空格隔开的正整数,表示 Ki。

输出格式
最少按键次数,若无法到达,则输出-1。

样例输入

5 1 5
3 3 1 2 5

样例输出

3

代码

#include <iostream>
#include <cstdio>
#define inf 100000 //设置上限
using namespace std;int n, A, B, cnt = inf;
int a[205];
bool v[205]; //标记剪枝数组bool check(int k, int i) {if (i == 0) {if (k + a[k] > n) //不飞冲天return 0;} else {if (k - a[k] < 1) //不下阴间return 0;}return 1;
}void dfs(int k, int s) {if (k == B) {cnt = min(cnt, s);} else if (cnt >= s) {v[k] = 1;if (check(k, 0) && !v[k + a[k]]) //上行dfs(k + a[k], s + 1);if (check(k, 1) && !v[k - a[k]]) //下行dfs(k - a[k], s + 1);v[k] = 0;}
}int main() {scanf("%d%d%d", &n, &A, &B);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}dfs(A, 0);if (cnt == inf)printf("-1");elseprintf("%d", cnt);
}

【集训】DFS/BFS专训2相关推荐

  1. 【集训】DFS/BFS专训3

    DFS/BFS专训3 文章目录 DFS/BFS专训3 A. 生日蛋糕 B. 埃及分数 C. 最优贸易 D. 关系网络 E. 四色地图 F. 小猫爬山 G. 最大黑区域 H. 引水入城 I. 武士风度的 ...

  2. 【DFS/BFS】NYOJ-58-最少步数(迷宫最短路径问题)

    [题目链接:NYOJ-58] 经典的搜索问题,想必这题用广搜的会比较多,所以我首先使的也是广搜,但其实深搜同样也是可以的. 不考虑剪枝的话,两种方法实践消耗相同,但是深搜相比广搜内存低一点. 我想,因 ...

  3. POJ2308连连看dfs+bfs+优化

    DFS+BFS+MAP+剪枝 题意:       就是给你一个10*10的连连看状态,然后问你最后能不能全部消没? 思路:      首先要明确这是一个搜索题目,还有就是关键的一点就是连连看这个游戏是 ...

  4. 链式前向星模板 建图+dfs+bfs+dijkstra

    边没有用struct封装起来,节点和边的计数起点如果不符合习惯可以稍作修改 建图+DFS+BFS #include <cstdio> #include <cstring> #i ...

  5. matlab hist函数_算法工匠MATLAB专训营:Matlab绘图,小试牛刀

    作者 | 蔡老师 仿真秀专栏作者 首发 | 仿真秀平台 导读:正文之前,我在此详细说明一下,因为本文包含的程序太难得,网上肯定找不到这样的程序.随着讲课的越来越深入,我给出的程序会越来越实用,接近于实 ...

  6. 算法 - DFS/BFS

    DFS函数大概率会传递"位置信息",根据位置信息获取下一步的选择,(大部分是在循环中)选择.执行.回退 例如N皇后的 棋盘位置(x, y),组合问题的 idx DFS函数的目的是, ...

  7. [Leetcode][第130题][JAVA][被围绕的区域][DFS][BFS]

    [问题描述][中等] [解答思路] 1. 深度优先搜索 使用深度优先搜索实现标记操作.在下面的代码中,我们把标记过的字母 O 修改为字母 A. 复杂度 class Solution {int[] dx ...

  8. 1.5万字详述 | 全开源:python写小游戏+AI强化学习与传统DFS/BFS控制分别实现

    简介:本周的强化学习我们来到实践部分.我以我在 GitHub 上开源的项目 PiperLiu / Amazing-Brick-DFS-and-DRL 为对象,从零开始与各位朋友分享:如何用 pytho ...

  9. java bfs dfs_java优先搜索(DFS/BFS)实际应用

    深度优先搜索DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.广度优先搜索BFS是Breadth First Sear ...

最新文章

  1. Apache Hadoop 2.4.1 单节点安装
  2. 解决intellij IEDA mapper.xml文件警告以及could not autowire的错误提示
  3. 『ACM-算法-lowbit』算法竞赛进阶指南--lowbit运算,找到二进制下所有是1的位
  4. jmeter(四十五)常用Beanshell脚本
  5. NET问答: String 和 string 到底有什么区别?
  6. std::map用法
  7. oracle命令行打不开,关于oracle命令行上下左右键没法使用解决办法
  8. 浅谈“三层结构”原理与用意(转帖)
  9. 10个你应该了解的Git命令(以及Git省时小窍门)
  10. idea java no sdk_java - intelliJ IDEA 13错误:请选择Android SDK
  11. jQuery 对象与Dom 对象互转
  12. 使用csscan评测字符集改变
  13. 风尚云网学习-本地拖拽文件夹实现gitee码云代码文件提交
  14. 免费下载3小时学会Excel数据处理视频教程
  15. 2022年Cs231n PPT笔记-训练CNN
  16. 共探机遇 2018中国产业互联网化纤创新者大会华丽启幕...
  17. boost1.79编译
  18. 炼丹心得|追求极致的比赛冠军什么样?
  19. Bootstrap学习(三)——Bootstrap 插件
  20. win10系统作为文件服务器,win10作为云服务器吗

热门文章

  1. mysql统计个数_mysql查询统计数量
  2. 个人征信已开放,互联网巨头如何行动
  3. QQ空间过滤器,千军万马(97779)网盘资源下载地址提取器,Discuz 论坛隐藏内容自动回复 成功上架到 chrome 商店...
  4. 主题模型TopicModel:Unigram、LSA、PLSA模型
  5. 小批量制造企业生产计划
  6. 微软新编程字体开源,用着一不小心就骂人了
  7. 可乐瓶游戏c语言,小班体育游戏《玩可乐瓶》教案
  8. android 录音获取分贝变化,Android录音时获取分贝值的方法代码实例
  9. 用正温度系数的热敏电阻PT100如何设计温度采集电路?
  10. 鱼香ROS网站上线|一行代码安装ROS/ROS2/解决rosdep问题|小鱼脚本