DFS的一天

今天写了三题DFS

1.找连通块 kuangbin专题1-12题

这题用BFS和DFS都可以,DFS代码简单,但是BFS要快一点,但也差不多,套路都差不多

这是DFS找连通块

//date:2020.4.16
//author:lujunfeng
#include <bits/stdc++.h>
using namespace std;
int step[8][2]= {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}};
int grid[100][100];
int m,n;
void dfs(int x,int y)
{
//queue<pair<int,int> > pa;
grid[x][y]=0;
for(int i=0; i<8; i++)
{
int nexti=x+step[i][0];
int nextj=y+step[i][1];
if(nexti>=0&&nextj>=0&&nexti<m&&nextj<n&&grid[nexti][nextj])
{
grid[nexti][nextj]=0;
dfs(nexti,nextj);
}
}
}

int main()
{
cin>>m>>n;
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
char a;
cin>>a;
if(a=='@')
grid[i][j]=1;
else
grid[i][j]=0;
}
}
int cnt=0;
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
if(grid[i][j]==1)
{
dfs(i,j);
cnt++;
}
}
cout<<cnt<<endl;
return 0;
}

这是BFS

//date£º2020.4.16
//author:lujunfeng
#include<iostream>
#include<queue>
#include<string>
using namespace std;
int m, n;
int step[8][2] = { {1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1} };
const int INF = 1e5;
int grid[105][105];
void bfs(int x, int y)
{
queue<pair<int, int> > q;
grid[x][y] = 0;
q.push(pair<int, int>(x, y));
while (!q.empty())
{
pair<int, int> t = q.front();
q.pop();
for (int i = 0; i < 9; i++)
{
int a = t.first, b = t.second;
a += step[i][0], b += step[i][1];
if (a>=0 && a<m && b>=0 &&b<n &&grid[a][b] )
{
grid[a][b] = 0;
q.push(pair<int, int>(a, b));
}
}
}
}
int main()
{
while (cin >> m >> n, m)
{
for (int i = 0; i < m; i++)
{
string s;
cin >> s;
for (int j = 0; j < n; j++)
{
if(s[j]=='@')
grid[i][j] = 1;
else
grid[i][j] = 0;
}
}
int cnt = 0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (grid[i][j])
{
bfs(i, j);
cnt++;
}
}
}
cout << cnt << endl;
}
return 0;
}

2.八皇后基础DFS

//八皇后问题练习
//date:2020.4.16
//author:lujunfeng
#include <bits/stdc++.h>
using namespace std;

int col[14],left0[28],right0[27];
int res,n;
//res记录可以放置的种数
void dfs(int l)
{
if(l>=n)
{
res++;
return;
}
for(int i=0; i<n; i++)//l表示一列一列的遍历
{
if(!col[i]&&!left0[l+i]&&!right0[l-i+n])
{
col[i]=1;
left0[l+i]=1;
right0[l-i+n]=1;
dfs(l+1);
col[i]=0;
left0[l+i]=0;
right0[l-i+n]=0;
}
}
}

int main()
{
cin>>n;
dfs(0);
cout<<res<<endl;
return 0;
}

3.棋盘问题

昨晚一晚上才搞懂这个代码,最关键的就是第二个dfs(line+1),是由于存在可以一行的没有一个元素被选,所以要跳过这一行,继续下一行,当然了,要加终点判断条件,if(line>n)超出了棋盘,那必须结束

 

//棋盘问题 DFS进阶
//date:2020.4.16
//author:lujunfeng
#include <bits/stdc++.h>
using namespace std;
int grid[100][100];
int n,k;//n为棋盘大小,k为可放棋子个数
int cnt;//结果
int way;//已走的步数
int vis[100];//用来记录该列有没有放棋子
void dfs(int line)
{
if(way==k)
{
cnt++;
return ;
}
if(line>n)
return ;
for(int i=0; i<n; i++)
{
if(vis[i]==0&&grid[line][i]==1)
{
vis[i]=1;
way++;
dfs(line+1);
way--;
vis[i]=0;
}
}
dfs(line+1);//说明line行没有放一个棋子,于是要跳过该行,要不然没有全部扫完就结束了
}
int main()
{
cin>>n>>k;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
char a;
cin>>a;
if(a=='#')
grid[i][j]=1;
else
grid[i][j]=0;
}
}
dfs(0);
cout<<cnt<<endl;
return 0;
}

 

继续加油吧!

posted @ 2020-04-16 21:42  someonezero  阅读(115)  评论(0编辑  收藏  举报