栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言 N皇后问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 //偷懒用了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< 
以上! 

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1012939.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号