【回溯法】8个皇后怎么摆?

8*8的棋盘摆8个皇后,任意两个皇后不得再同一行、同一列、同一对角线上。总共有多少种解法?

由于任意两个皇后不能在同一行,那就是每个皇后单独占据一列。
定义数组ColumnIndex,表示在第i行,ColumnIndex[i]列有一个皇后。
用0~7初始化数组可以使任意两个皇后都不在同一行同一列上,再对数组做全排列,用回溯法,找到符合排列的数组即任意两个都不在同一对角线上
i - j == arr[i] - arr[j] || j - i == arr[i] - arr[j]

void eightQ_init()
{
	int ColumnIndex[8];
	for (int i = 0; i < 8; ++i)
	{
		ColumnIndex[i] = i;
	}
	clock_t start = clock();
	eightQueen(ColumnIndex);
	cout << "time:" << clock() - start << "ms"<<endl;
}

时间还挺快

void eightQueen(int arr[])
{
	if (arr == nullptr)
		return;

	eightQueenCore(arr, 0);
}
//递归
void eightQueenCore(int arr[], int idx)
{
	if (idx == 8 )
	{
		if (eight_check(arr))
		{
			eight_printarr(arr);
			eight_display(arr);
		}
	}
	else
	{
		for (int i = idx; i < 8; i++)
		{
			//交换
			swap(arr[i], arr[idx]);
			eightQueenCore(arr, idx + 1);
			//回溯
			swap(arr[i], arr[idx]);
		}
	}
}
//检查是否符合8皇后排列
bool eight_check(int arr[])
{
	//可以看作行号
	for (int i = 0; i < 8; ++i)
	{
		//看作列号
		for (int j = i+1; j < 8; ++j)
		{
			//如果对角线上有就说明不符合条件
			if (i - j == arr[i] - arr[j] || j - i == arr[i] - arr[j])	return false;
		}
	}
	return true;
}
//打印数组
void eight_printarr(int arr[])
{
	cout << "[" << cnt++ << "]";
	for (int i = 0; i < 8; ++i)
		cout << arr[i] << " ";
	cout << endl;
}
//打印棋盘
void eight_display(int arr[])
{
	for (int idx = 0; idx < 8; idx++)
	{
		char chessboard[8] = { '-','-','-' ,'-' ,'-' ,'-' ,'-' ,'-' };
		int col = arr[idx];
		chessboard[col] = '*';
		cout << "\t";
		for (auto c : chessboard)
		{
			cout << c;
		}
		cout << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值