0
点赞
收藏
分享

微信扫一扫

他喵的DFS

Villagers 2022-01-26 阅读 29
算法

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;
 }

在这里插入图片描述

在这里插入图片描述

举报

相关推荐

0 条评论