C语言 N皇后问题

C语言 N皇后问题

介绍:什么是N皇后问题
  • 国际象棋中,皇后是一个很强力的单位,可以朝着以皇后棋子本身位置为中心,横向和纵向以及 斜率为1和-1的方向上移动,N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,并且使得任何两个 皇后不同行,不同列也不在同一条斜线上。

这个问题我用的是回溯的方法:
以4x4的棋盘为例:
我们先在第一行取第一列的位置,此位置没有与其他皇后行走范围冲突,因此可以放

1234
1Qqqq
2qq
3qq
4qq

第二行同样从第一列开始取,当取到第一列,冲突,第二列,冲突,第三列不冲突,放置第二枚皇后

1234
1Qqqq
2qqQq
3qqqq
4qqq

第三行重复第二行的操作,但是发现任何列都会冲突,因此不能放,我们回到第二行,将皇后向下一列放置

再来到第三行此时第二列没有冲突,则可以放

1234
1Qqqq
2qqqQ
3qQqq
4qqqq

我们发现第四行又没有可选择的了。第一次重试失败,回溯上一级,无可用列,再回溯上一级,无可用列,最后返回第一行。

第二次重试
我们重新回到第一步,这说明我们之前第一行选择第一列是无解的,所以我们第一行不应该选择第一列,我们再来选择第二列来试试,以此类推

1234
1qQqq
2qq
3qq
4q

代码实现如

#include <bits/stdc++.h>//偷懒用了C++的万能头,其实和C没区别,.C文件编译不通过就换C的头
using namespace std;

bool attack(int *chess, int col, int row)
{
	for(int i = 0; i < row; ++i){
		if(chess[i] == col){//纵向冲突
			return true;
		}
		if(col - chess[i] == row - i || chess[i] - col == row - i){
		//斜线冲突
			return true;
		}
	}
	return false;
}

int nqueen()
{
	int queens = 0;
	cin>>queens;
	int col = 0, cnt = 0, row = 0;
	int chess[9] = {-1};
	//题目要求是最多9个皇后,而且网站的编译器不允许数组长度为变量。
	while(!(col == queens && row == 0)){
		if(!attack(chess,col,row)){//判断无冲突
			chess[row++] = col;
			if(row == queens){//已将所有皇后防止完成
				++cnt;
				col = chess[--row];//回溯上一行寻找新解
				++col;
				while(col == queens){//上一行已经是最后一个的情况则再向上回溯
					if(queens == 1){
						col = queens;
						row = 0;
						break;
					}	
					chess[row--] = -1;
					col = chess[row];
					col++;
				}
			}
			else{
				col = 0;
			}
		}
		else{
            ++col;//有冲突则下一列
            while(col == queens && row != 0){//全列都有冲突则回溯
                chess[row--] = -1;
				col = chess[row];
                col++;
            }
        }
	}
	return cnt;
}

int main()
{
	int cnt = 0;
	cnt = nqueen();
	cout<<cnt;
	return 0;
}

以上!

希望能给你一点帮助。
感谢

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值