DFS全排列
#include<stdio.h>
#include<cstdlib>
#include<iosteream>
using namespace std;
int a[100];//盒子,装数字
int v[100];//v[i]表示i数字有没有在盒子里面 ,0没有在里面,1表示在里面
void dfs(int step)//走到第step个盒子面前的情况
{
//递归出口
if(step==n+1)
{
//输出一组解
for(int i=1;i<=n;i++)
{printf("%d",a[i]);
}
printf("\n");
return;
}
//面临n中选择
for(int k=1;k<=n;k++)
{
if(v[k]==0)//表示k没有装入盒子
{
a[step]=k;
av[k]=1;
dfs(step+1);
//回溯
v[k]=0;
}
}
return;
}
int main()
{
cin>>n;
dfs(1);
return 0;
}
DFS子集
#include<stdio.h>
#include<cstdlib>
#include<iostream>
using namespace std;
int m;
int a[100];//a保存1-n
struct node
{
int x;
int b[100];
};
struct node n;//保存子集
void dfs(int cur)//当前面临第cur个数字的情况,分为选与不选
{
//边界出口
if(cur==m)
{
//输出子集
for(int i=0;i<n.x;i++)
{
cout<<n.b[i]<<"";
}
cout<<endl;
return;
}
//选
n.b[n.x++]=a[cur];
dfs(cur+1);
n.x--;
//不选
dfs(cur+1);
}
int main()
{
cin>>m;
for(int i=0;i<m;i++)
a[i]=i+1;
dfs(0);
return 0;
}
DFS数独
#include<stdio.h>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N=10;
int a[N][N];
//数独
bool check(int x,int y,int k)
{
//检查同行同列
for(int i=0;i<9;i++)
{
if(a[x][i]==k)return false;
if(a[i][y]==k)return false;
}
//检查小九宫格
for(int m=(x/3)*3;m<(x/3+1)*3;m++)
for(int n=(y/3)*3;n<(y/3+1)*3;n++)
if(a[m][n]==k)return false;
return true;
}
void dfs(int x,int y)//当面临(x,y)这个格子的情况,该方何数字
{
if(x==9)
{
//输出这组解
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
if(a[x][y]==0)
{
//可以放1-9的某一个数字
for(int k=1;k<=9;k++)
{
if(check(x,y,k))
{
a[x][y]=k;
dfs(x+(y+1)/9,(y+1)%9);//换行
a[x][y]=0;//回溯
}
}
}
else
{
dfs(x+(y+1)/9,(y+1)%9);//换行
}
}
int main()
{
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
cin>>a[i][j];
dfs(0,0);
return 0;
}
DFS 皇后问题
对角线上不能放2个皇后
#include<stdio.h>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N=10;
int a[N];//a[i]表示第i行上的皇后放于a[i]列上,假设a[3]=7
int cnt,n;
bool check(int x,int y)
{
for(int i=1;i<=x;i++)
{
if(a[i]==y)return false;
if(i+a[i]==x+y) return false;
if(i-a[i]==x-y) return false;
}
}
void dfs(int row)//表示第 row皇后放于何处
{
if(row==n+1)
{
//产生了一组解
cnt++ ;
return;
}
for(int i=1;i<=n;i++)
{
if(check(row,i))
{
a[row]=i;
dfs(row+1);
a[row]=0;
}
}
}
int main()
{
cin>>n;
dfs(1);
cout<<cnt;
return 0;
}
DFS 马走日问题
#include<stdio.h>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N=10;
int T,n,m,x,y;
bool v[N][N];
int dir[8][2]={{-2,-1},{-1,-2},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
int ans;
void dfs (int x,int y,int cnt)
{
if(cnt==n*m)
{
ans++;
return ;
}
for(int i=0;i<8;i++)
{
int x1=x+dir[i][0],y1=y+dir[i][1];
if(x1<0||x1>=n||y1<0||y1>=m||v[x1][y1]) continue;
v[x][y]=true;
dfs(x1,y1,cnt+1);
v[x][y]=false;//恢复现场
}
}
int main()
{
cin>>T;
for(int i=1;i<=T;i++)
{
ans=0;
scanf("%d%d%d%d",&n,&m,&x,&y);
dfs(x,y,1);
printf("%d\n",ans);
}
return 0;
}
DFS染色问题
#include<stdio.h>
#include<cstdlib>
#include<iostream>
using namespace std;
int a[100][100];
int v[100][100],n,m,sum;
//定义一个方向数组
int next[4][2]{{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0}};//向上走
void dfs(int x,int y)
{
int tx,ty;
for(int k=0;k<=3;k++){
tx=x+next[k][0];
ty=y+next[k][1];
//判断是否越界
if(tx<1||tx>n||ty<1||ty>m)
continue;
//判断是否陆地
if(a[tx][ty]>0&&v[tx][ty]==0){
sum++;
v[tx][ty]=1;
dfs(tx,ty);
}
}
return;
}
int main()
{
int startx,starty;
scanf("%d%d%d%d",&n,&m,&startx,&starty);
//读入地图
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
v[startx][starty]=1;
sum=1;
dfs(startx,starty);
printf("%d\n",sum);
return 0;
}