DFS【Acwing】

排列数字

给定一个整数 n n n,将数字 1 ∼ n 1∼n 1n 排成一排,将会有很多种排列方法。

现在,请你按照字典序将所有的排列方法输出。

输入格式
共一行,包含一个整数 n n n

输出格式
按字典序输出所有排列方案,每个方案占一行。

数据范围
1 ≤ n ≤ 7 1≤n≤7 1n7
输入样例:

3

输出样例:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

代码:

package main

import "fmt"

var n int
var path [10]int
var st [10]bool

func main() {
	fmt.Scan(&n)
	dfs(0)
}

func dfs(u int) {
	if u == n {
		for i := 0; i < n; i++ {
			fmt.Printf("%d ", path[i])
		}
		fmt.Println()
		return
	}

	for i := 1; i <= n; i++ {
		if !st[i] {
			path[u] = i
			st[i] = true
			dfs(u + 1)
			st[i] = false
		}
	}
}

n-皇后

n − n− n皇后问题是指将 # n n n 个皇后放在 n × n n×n n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

1_597ec77c49-8-queens.png
现在给定整数 n n n,请你输出所有的满足条件的棋子摆法。

输入格式
共一行,包含整数 n n n

输出格式
每个解决方案占 n n n 行,每行输出一个长度为 n n n 的字符串,用来表示完整的棋盘状态。

其中 . 表示某一个位置的方格状态为空, Q Q Q 表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

注意:行末不能有多余空格。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围
1 ≤ n ≤ 9 1≤n≤9 1n9
输入样例:

4

输出样例:

.Q..
...Q
Q...
..Q.

..Q.
Q...
...Q
.Q..

代码:

在这里插入图片描述

package main

import "fmt"

var n int

//代表列、对角线、反对角线
//注意对角线的表示范围
var col, dg, udg []bool //[0, 2n]
var arr [][]rune

func main() {
	fmt.Scan(&n)
	arr = make([][]rune, n)
	for i := 0; i < n; i++ {
		arr[i] = make([]rune, n)
	}
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			arr[i][j] = '.'
		}
	}
	col = make([]bool, 2*n)
	dg = make([]bool, 2*n)
	udg = make([]bool, 2*n)
	dfs(0)
}

//按行枚举 u代表某一行
func dfs(u int) {
	if u == n {
		//所有行遍历完成 打印结果
		for i := 0; i < n; i++ {
			for j := 0; j < n; j++ {
				fmt.Printf("%s", string(arr[i][j]))
			}
			fmt.Printf("\n")
		}
		fmt.Printf("\n")
		return
	}

	for i := 0; i < n; i++ {
		//剪枝 (u,i)这个点需要保证该列 该对角线 以及反对角线都没有其他的Q
		if !col[i] && !dg[u+i] && !udg[i-u+n] {
			arr[u][i] = 'Q'
			col[i] = true
			dg[u+i] = true
			udg[i-u+n] = true
			dfs(u + 1)
			//回溯 恢复现场
			col[i] = false
			dg[u+i] = false
			udg[i-u+n] = false
			arr[u][i] = '.'
		}
	}
}

在go中,没有char类型,使用rune来表示,rune本质上还是整数,输出的时候需要转换成string

c := 'Q'
string(c) //Q
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值