这一周主要以练习深度优先搜索与广度优先搜索为主,看了40篇与BFS和DFS有关题目的题解;复习了5篇涉及STL的题解;还有5篇思维题目。对于一个题目如果不告诉涉及深搜或广搜的话,靠自我判断还是不够迅速,与其他相结合使用的熟练度有所提高,但还需加强。下面由以下两个方面对本周学习进行分析:
一、深度优先搜索分析
1、八皇后问题
题意:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一
行、同一列或同一斜线上,问有多少种摆法。
#include<iostream>
using namespace std;
int n;
int row[101]={0},column[101]={0},l_diagonal[101]={0},r_diagonal[101]={0};
int a[101];//记录是否可以放置皇后
int sum=0;//记录可行方案数
void dfs(int x);
int main()
{
cin>>n;
dfs(1);
cout<<sum<<endl;
return 0;
}
void dfs(int x)
{
int y;
int i;
if(x==n+1)//如果到达终点,说明方案成功
{
sum++;
}
for(y=1;y<=n;y++)
{
if(!row[x]&&!column[y]&&!l_diagonal[x-y+n]&&!r_diagonal[x+y])//如果行、列、左对角线、右对角线均可以下
{
a[x]=y;//说明该点可以放置一皇后,记录
row[x]=1;
column[y]=1;
l_diagonal[x-y+n]=1;
r_diagonal[x+y]=1;
dfs(x+1);
row[x]=0;
column[y]=0;
l_diagonal[x-y+n]=0;
r_diagonal[x+y]=0;
}
}
}
2、财产分配问题 AOJ 0118:Property Distribution
题意:一块矩形的区域,里面有三种字符,分别为@#*,把相邻的相同字符连接成整体,问可以分成多少块。
部分代码:
char tmap[1000][1000];
int w,h;
int ans;
int dfs(int x,int y,char seed){
if(x<0 || x>w || y>h || y<0) return 0;
if(tmap[x][y]==0 ||seed != tmap[x][y]) return 0;
tmap[x][y] = 0;
dfs(x,y-1,seed);
dfs(x-1,y,seed);dfs(x+1,y,seed);
dfs(x,y+1,seed);
return 1;
}
二、广度优先搜索
1、序列反转
题目:给定序列1 2 3 4 5 6,再给定一个k.对于序列,我们可以将其中k个连续的数全部反转过来,例如k = 3的时候,上述序列经过1步操作后可以变成:3 2 1 4 5 6 ,如果再对序列 3 2 1 4 5 6进行一步操作,可以变成3 4 1 2 5 6.给定初始序列,以及结束序列,以及k的值,求出从初始序列到结束序列的转变至少需要几步操作?
2、填涂颜色 P1162 填涂颜色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题意:由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。要求把闭合圈内的所有空间都填写成2.
#include<bits/stdc++.h>
using namespace std;
#define maxn 35
int a[maxn][maxn],n;
int dx[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void bfs(int x,int y){
a[x][y]=0;
for(int i=0;i<4;i++){
int ux = x+dx[i][0],uy = y+dx[i][1];
if(ux>=0 and ux<=n+1 and uy>=0 and uy<=n+1 and a[ux][uy]==2){
bfs(ux,uy);
}
}
}
int main(){
for(int i=0;i<35;i++)for(int j=0;j<35;j++)a[i][j]=2;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int tmd;
cin>>tmd;
if(tmd==1)a[i][j]=1;
}
}
bfs(0,0);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
if(i!=n)cout<<endl;
}
return 0;
}