回溯问题:八皇后

问题介绍:

    在国际下象棋中,皇后可以在横、竖、斜线上不限步数吃掉其他棋子,故需要考虑怎么将8个皇后放在棋盘上(棋盘为8x8)。此为八皇后问题,为经典回溯算法问题,以下输出结果将输出‘*’为为方棋子的空位,‘@’为放置的皇后位置:
static char Queen[8][8];
static int a[8];   //a数组代表列冲突
static int b[15];  //b数组代表主对角线冲突
static int c[15];  //c数组代表从对角线冲突
static int iQueenNum = 0;  //记录总的棋盘状态数

void Cal(int i);  //i代表行数

int main()
{
	int iLine,iColumn;

	//棋盘初始化,空格为*,放置皇后的地方为@
	for(iLine=0;iLine<8;iLine++)
	{
		a[iLine] = 0;  //列标记初始化为0,表示无列冲突
		for(iColumn=0;iColumn<8;iColumn++)
			Queen[iLine][iColumn] = '*';
	}

	//主、从对角线标记初始化为0,表示没有冲突
	for(iLine=0;iLine<15;iLine++) 
		b[iLine]=c[iLine]=0;
	Cal(0);
	return 0;
} 

void Cal(int i)
{
	int iColumn;
	for (iColumn=0;iColumn<8;iColumn++)
	{
		if(a[iColumn]==0&&b[i-iColumn+7]==0&&c[iColumn+i]==0)
			//如果没有冲突存在
		{
			Queen[i][iColumn] = '@';  //放皇后
			a[iColumn] = 1;           //下一次该列上不能放皇后
			b[i-iColumn+7] = 1;       //下一次该主对角线上不能放皇后
			c[iColumn+i] = 1;         //下一次该从对角线上不能放皇后
			if(i<7) Cal(i+1);         //如果行还没有遍历完,进入下一行
			else  //否则输出
			{
				//输出棋盘状态
				int iLine,iColumn;
				printf("第%d种状态为:\n",++iQueenNum);
			for(iLine=0;iLine<8;iLine++)
			{
				for(iColumn=0;iColumn<8;iColumn++)
					printf("%c",Queen[iLine][iColumn]);
				printf("\n");
			}
			printf("\n\n");
			}

			//如果前次的皇后导致后面放置无论如何都不能满足要求,则回溯,重置
			Queen[i][iColumn] = '*';
			a[iColumn] = 0;
			b[i-iColumn+7] = 0;
			c[iColumn+i] = 0;
		}
	}
}

输出结果为:


共92种解法,即92种不同排放方法。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值