目录
1, 棋盘挑战
这道题和八皇后非常类似,具体的做法不再加以追叙,每一行代码都有备注
#include <bits/stdc++.h>
using namespace std;
const int N=15;
int path[N],ans,n;
bool col[N],dg[N*2],udg[N*2];//对角线的个数为N*,用于判断每一行、列,和对角线与反对角线有没有多余一个棋子;
void dfs(int x)//暴搜每一行
{
if(x>n)//这个分支完成搜素,符合条件,
{
ans++;//答案加一
if(ans<=3)//根据要求,输出字典序的前三种方案,
{
for(int i=1;i<=n;i++)
cout<<path[i]<<' ';
cout<<endl;
}
return;
}
for(int y=1;y<=n;y++)//暴搜每一列有没有数
{
if(!col[y]&&!dg[x+y]&&!udg[x-y+n])//这个棋子符合摆放条件
{
path[x]=y;//记录摆放位置
col[y]=true,dg[x+y]=true,udg[x-y+n]=true;
dfs(x+1);//又继续暴搜x+1行
col[y]=false,dg[x+y]=false,udg[x-y+n]=false;//不符合条件的话,需要恢复现场
path[x]=0;
}
}
}
int main(){
cin>>n;
dfs(1);
cout<<ans<<endl;
}
2、马蹄铁
这道题每行代码有注释,不再单独写题解了
#include <bits/stdc++.h>
using namespace std;
const int N=10;
char h[N][N];
bool g[N][N];//g[N][N]用于标记这个方格是否被搜过
int ans,n;//用以记录(和)的数量,
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//定义偏移量
void dfs(int x,int y,int l,int r)
{
g[x][y]=true;
if(l==r)//找到了符合条件的字符串
{
ans=max(ans,l+r);
g[x][y]=false;//恢复现场
return;
}
for(int i=0;i<4;i++)//枚举上下左右的四个方格
{
int a=x+dx[i];
int b=y+dy[i];
if(a>=0&&a<n&&b>=0&&b<n&&!g[a][b])//没有越界且给g[a][b]没有被标记
{
if(h[a][b]=='('&&h[x][y]==')')continue;//")("这种一定不符合条件
if(h[a][b]=='(')dfs(a,b,l+1,r);//l++
else
dfs(a,b,l,r+1);//r++
}
}
g[x][y]=false;//恢复现场
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>h[i][j];
if(h[0][0]=='(')//她只能移动到包含马蹄铁的方格区域内,当她进入该区域时就会拿起那里的马蹄铁 //如果是')',怎么拿ans都会是0
dfs(0,0,1,0);//第一个方格符合条件,
cout<<ans;
return 0;
}
错误反思:二维数组的输入没有正确,边界没有处理对
3、不同路径数
#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;
unordered_set<int> ans;//开一个哈希表用于存数
const int N=8;
int g[N][N],n,m,k;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//偏移量用于上下左右走步
void dfs(int x,int y,int u,int num)//当前在走第u步,积累的数是num
{
if(u==k)//已经走了k步了
{
ans.insert(num);
return ;//结束一次枚举
}
else
{
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];//上下左右走
if(a>=0&&a<n&&b>=0&&b<m)//位置没有越界
{
dfs(a,b,u+1,num*10+g[a][b]);
}
}
}
}
int main(){
cin>>n>>m>>k;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
cin>>g[i][j];//输入数据
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
dfs(i,j,0,g[i][j]);//开始枚举,第一个数是g[i][j];
}
printf("%d\n",ans.size());
return 0;
}
对于unordered_set,可看这篇文章
对于dfs算法,在后期我会继续更新,也会更加详细