寒假集训——BFS、DFS
今日集训学习了新的算法(只对我来说,别人都会了,呜呜)。
===========================================================
关于BFS和DFS感觉理解并不困难(递归+回溯),但是如何使用,如何运用,感觉不太容易。上午上完课后,剩下时间走了个迷宫就走了一个多小时,唉~~~。
接下来分享今日的做题训练。
1. B3625 迷宫寻路
bfs做法
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
char s[N][N];
bool bfss[N][N];//用于标记是否走过
queue<pair<int, int>>qu;
void bfs() {
qu.push({1, 1});
bfss[1][1] = 1;//走过则为1
// 判断队列是否为空
while (qu.size() != 0) {
auto t = qu.front();
// 取队头
qu.pop();
// 抛出
int i;
if (t.first == n && t.second == m) {
// 如果走到(n,m)
cout << "Yes" << endl;
exit(0);//结束程序
}
for (i = 0; i < 4; i++) {
//遍历偏移量
int x = t.first + dx[i];
int y = t.second + dy[i];
// cout << x << " " << y << endl;
if (x > 0 && y > 0 && x <= n && y <= m && bfss[x][y] == 0 && s[x][y] == '.') {
bfss[x][y] = 1;
// 标记
qu.push({x, y});
// 入队
}
}
}
}
int main() {
cin >> n >> m;
int i, j;
for (i = 1; i <= n; i++) {
for (j = 1; j <= m; j++) {
cin >> s[i][j];
}
}
bfs();
cout << "No" << endl;
}
dfs做法
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
char s[N][N];
bool dfss[N][N];
void dfs(int nx, int ny) {
if (nx == n && ny == m) {
cout << "Yes" << endl;
exit(0);
}
for (int i = 0; i < 4; i++) {
int x = nx + dx[i];
int y = ny + dy[i];
// cout << x << " " << y << endl;
// cout << nx << " " << ny << endl;
if (s[x][y] == '#')
continue;
if (dfss[x][y] == 1)
continue;
if (x <= 0 || x > n || y <= 0 || y > m)
continue;
dfss[x][y] = 1;
dfs(x, y);
//dfss[x][y]=0;
}
}
int main() {
cin >> n >> m;
int i, j;
for (i = 1; i <= n; i++) {
for (j = 1; j <= m; j++) {
cin >> s[i][j];
}
}
dfss[1][1] = 1;
dfs(1, 1);
cout << "No" << endl;
return 0;
}
------------------------------------------------
2. P1162 填涂颜色
奇奇怪怪的染色问题,相当抽象。
#include<bits/stdc++.h>
using namespace std;
int a[100][100];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
bool bfss[100][100];
int n;
queue<pair<int, int>>qu;
//bfs
void bfs() {
qu.push({0, 0});
int i, j;
while (!qu.empty()) {
auto t = qu.front();
qu.pop();
int x = t.first;
int y = t.second;
a[x][y] = 0;
for (i = 0; i < 4; i++) {
if (a[x + dx[i]][y + dy[i]] == 2) {
qu.push({x + dx[i], y + dy[i]});
}
}
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return;
}
int main() {
cin >> n;
int i, j, x, y;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
cin >> a[i][j];
}
}
for (i = 0; i <= n + 1; i++) {
for (j = 0; j <= n + 1; j++) {
if (a[i][j] == 0)
a[i][j] = 2;
}
}
bfs();
}
———————————————————————
3.B3621 枚举元组
呜呜呜,不如暴力。
#include<bits/stdc++.h>
using namespace std;
int a[100];
int n, k;
void dfs(int x) {
if (x == n + 1) {
for (int i = 1; i <= n; i++) {
cout << a[i] << " ";
}
cout << endl;
return;
}
for (int i = 1; i <= k; i++) {
a[x] = i;
dfs(x + 1);
}
}
int main() {
cin >> n >> k;
dfs(1);
return 0;
}
———————————————————————
4.842. 排列数字
相似题目。
给定一个整数 \(n\) ,将数字 \(1∼n\)
排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
输入格式:
共一行,包含一个整数 \(n\)。
输出格式:
按字典序输出所有排列方案,每个方案占一行。
数据范围:
\(1≤n≤7\)
输入样例:
\(3\)
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include<iostream>
using namespace std;
int n;
int a[1010];
bool dog[1010];
// 标记数组
void dfs(int x)
{
int i;
if(x==n+1)
{
for(i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for(i=1;i<=n;i++)
{
if(dog[i]==0)
{
a[x]=i;
dog[i]=1;
dfs(x+1);
dog[i]=0;
}
}
}
int main()
{
cin>>n;
dfs(1);
return 0;
}