dfs深度优先遍历(全排列,数独)

(1)全排列

1.什么是全排列
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

2.例子
假设现在有一个数组ar如下

ar[3]={1,2,3};
那么这个数组的全排列就是

1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
 

#include<iostream>
using namespace std;
	int n;
int a[100]={0};
int flag[100]={0};//用于标志1-n已经被使用与否 
int dfs(int times){
//	cout<<times<<endl;
int i;
	if(times-1==n){
		for(int i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0 ;
	}
	else{
		for( i=1;i<=n;i++){
		if(!flag[i]){
			
				a[times]=i; 
				flag[i]=1;
		dfs(times+1);//易错,不能写为times++,这样会改变times的值 
	flag[i]=0;
		
		}	
	}
	}
	

}
int main(){

	cin>>n;
	
	dfs(1);
}

(2)盾神与困难数独

问题描述

  有一天,盾神接触到了风靡世界的小游戏——数独!!!盾神非常感兴趣,不惜翘课用了一天的时间把数独玩得出神入化!!!于是他要过来考考你。经过“盾神与简单数独”的磨练后,你会做9*9的了。

输入格式

  输入为9*9的矩阵,如果第i行第j列为0,则该格子未填数;否则该格子已经有数。

输出格式

  输出为1个9*9的矩阵,表示字典序最小的方案。如无解则输出NO。
  矩阵大小关系的定义:第一关键字为a[1][1],第二关键字为a[1][2],……第四关键字为a[1][4],第五关键字为a[2][1],以此类推。矩阵A小于矩阵B,当且仅当存在k,A和B的前k-1个关键字的值都相等,而A的第k个关键字的值小于B的第k个关键字的值。矩阵A等于矩阵B,当且仅当A小于B和B小于A都不成立。
  字典序升序的定义:在矩阵序列a中,对于任意的i<=j,有a[i]<=a[j]。

样例输入

1 2 3 4 5 6 7 8 9
2 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0

样例输出

NO

样例输入

1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

样例输出

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
2 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 2 9 7 8
6 4 2 9 7 8 5 3 1
9 7 8 5 3 1 6 4 2

数据规模和约定

  矩阵中所有数的值为0到9。

数独的规则以及元素 - 知乎 (zhihu.com)

https://zhuanlan.zhihu.com/p/57044138

 

 

(4)三 羊 生 瑞 气

(如果有对齐问题,可以参看【图1.jpg】)

c8f47a7d2c5c2f3612d05bd71418ab9f.png

其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。

请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。

答案:1085

方法一:八层循环

方法二:递归搜索

//error

#include<iostream>
using namespace std;
	int a[8]={0};
	int n=8;
	int flag[10]={0};
	
	void dps(int times){
		if(times==n&&a[4]<=1){
		int q=0,w=0,e=0,r=0;
				//for(int i=0;i<n;i++)cout<<a[i]<<"-";
			//	cout<<endl;
			if(a[3]+a[1]==a[7]||a[3]+a[1]==a[7]+10){
				if(a[3]+a[1]>=10)q=1;
			
				if(a[2]+a[6]+q==a[1]||a[2]+a[6]+q==a[1]+10){
					if(a[2]+a[6]+q>=10)w=1;
					
					if(a[1]+a[5]+w==a[2]||a[1]+a[5]+w==a[2]+10){
							if(a[1]+a[5]+w>=10)e=1;
						
			if(a[0]+a[4]+e==a[5]||a[0]+a[4]+w==a[5]+10){
			if(a[0]+a[4]+e>=10)r=1;
			//cout<<"r:"<<r<<"  ";
			
				//cout<<a[4]<<endl;
			//	if(r==a[4])
					for(int i=0;i<n;i++)cout<<a[i]<<"  ";
		
		cout<<endl;
		
			}
					}
				}
			}
			
		}
		else{
			for(int i=0;i<=9;i++){
				if(!flag[i]){
					a[times]=i;
				flag[i]=1;
				dps(times+1);
				flag[i]=0;	
				}
			
			}
		}
		
	}
int main(){
dps(0);
}

 (5)

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半截詩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值