1.DFS练习:P1219 [USACO1.5] 八皇后 Checker Challenge https://www.luogu.com.cn/problem/P1219
规律:左斜线上每个点的横纵坐标之和相等,并且对角线不同其和也不同;右斜线上每个点的横纵坐标之差相等,但为了防止出现负数,要加上n。
#include<bits/stdc++.h>
using namespace std;
int n,sum=0,check[3][30]={0},arr[20];
void dfs(int line){
if(line>n){//如果所有皇后都放置完毕,增加计数
sum++;
if(sum>3){//输出前三次解
return;
}else{
for(int i=1;i<=n;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
return;
}
}
for(int j=1;j<=n;j++){//尝试在当前行的每一列放置皇后
if(!check[0][j]&&!check[1][line+j]&&!check[2][line-j+n]){//判断当前位置是否合法
arr[line]=j;//放置皇后
check[0][j]=1;//表示第j列不可以放置皇后
check[1][line+j]=1;//表示右斜线不可以放置皇后
check[2][line-j+n]=1;//表示左斜线不可以放置皇后
dfs(line+1);// 继续放置下一行的皇后
check[0][j]=0;
check[1][line+j]=0;
check[2][line-j+n]=0;
}
}
}
int main(){
cin>>n;
dfs(1);
cout<<sum;
return 0;
}
2.P1162 填涂颜色 https://www.luogu.com.cn/problem/P1162
拓展边界,将圈外的0连续起来,通过bfs将圈外的0标记为已访问。
#include<bits/stdc++.h>
using namespace std;
int a[35][35]={0},v[35][35]={0};//定义二维数组a和v,表示方阵和访问状态
int n;
struct point {
int x, y;
};
queue<point> p1;//定义队列p1,用于存储待访问的点
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
int main(){
cin>>n;
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
cin>>a[i][j];//输入方阵的每个格子值
}
}
v[0][0]=1;//将起点标记为已访问
p1.push(point{0,0});//将起点加入队列
while (!p1.empty()){
point p2 = p1.front();//取出队列中的第一个点
p1.pop();//弹出队列中的第一个点
for (int i=0;i<4;i++){
int tx=p2.x+dx[i],ty=p2.y+dy[i];//计算下一个点的坐标
if (tx<0||tx>n+1||ty<0||ty>n+1){//如果下一个点超出方阵范围,则跳过
continue;
}
if(a[tx][ty]==0&&v[tx][ty]==0){//如果下一个点是0且未访问过,则标记为已访问并加入队列
v[tx][ty]=1;
p1.push(point{tx,ty});
}
}
}
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
if (a[i][j]==0&&v[i][j]==0){//如果某个点是0且未访问过
cout<<2<<" ";
}else if(a[i][j]==1) {
cout<<1<<" ";
}else{//被访问过的0
cout<<0<<" ";
}
}
cout<<endl;
}
return 0;
}
<bits/stdc++.h>
是一个常见的 C++ 头文件引用语句,它包含了 C++ 标准库中的所有头文件。<iostream>:输入输出流,包括 cin、cout、cerr 等。
<vector>:向量容器,用于存储动态数组。
<queue>:队列容器,用于实现先进先出的数据结构。
<stack>:栈容器,用于实现后进先出的数据结构。
<algorithm>:算法库,包括排序、查找等常用算法。
<string>:字符串库,包括字符串操作和处理。
<cmath>:数学库,包括数学函数和常量。
queue
来存储待访问的点,通过 push()
将点加入队列,通过 front()
取出队列中的第一个点,通过 pop()
弹出队列中的第一个点,这样可以实现BFS算法中的层次遍历。
push()
:将元素添加到队列的末尾。pop()
:移除队列的第一个元素。front()
:返回队列的第一个元素。empty()
:检查队列是否为空。
BFS是一种图搜索的算法,目的是用于搜索检查每一个可以达到的点,直到找到结果为止。
bfs 遍历节点是先进先出,dfs遍历节点是先进后出;bfs是按层次访问的;dfs 是按照一个路径一直访问到底,当前节点没有未访问的邻居节点时,回溯到上一个节点,不断的尝试,直到访问到目标节点或所有节点都已访问。