n皇后问题

问题
在n*n格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后不能处于同一行、同一列或同一斜线上,有多少种摆法?

8皇后问题图解
8皇后问题图解

分析
采用回溯法。即在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。

‘回溯法’思路:
用数组模拟棋盘,从第一行开始,依次选择位置,如果当前位置满足条件,则向下选择位置,如果不满足条件,那么当前位置后移一位。
若最后一位不满足,则回溯到上一行,选择下一位,继续搜索尝试。

数组并不需要n*n,只需要一个n长度的数组来存储位置。
表示方式:arr[i]=k;
表示:第i行的第k个位置放一个皇后。这样一个arr[n]的数组就可以表示一个解。

算法
1、不在同一行:每一行放一个皇后,就解决了不在同一行的问题。
2、不在同一列:在第i行的时候,遍历n列,和之前所有行的皇后位置进行比较。当前列col不等于之前所有列,即col!=arr[i]。
3、不在同一斜线:(row-i)/(col-arr[i])!=1or-1,可以用绝对值函数:abs(row-i)!=abs(col-arr[i])。

判断方法:

int check(int row,int col)
{
	int i;
	for(i=0;i<row;i++)
	{
		if(col==arr[i]||abs(row-i)==abs(col-arr[i]))
			return 0;
	}
	return 1;
}

向下搜索和向前回溯

for(i=0;i<n;i++)
{
	if(check(row,i))
	{
		arr[row]=i;
		//同样方法搜索下一行(row+1)
	}
}

代码

#include<stdio.h>
#include<math.h>
int n,arr[8];
int count=0;
int check(int row,int col)
{
	int i;
	for(i=0;i<row;i++)
	{
		if(col==arr[i]||abs(row-i)==abs(col-arr[i]))
			return 0;
	}
	return 1;
}

void nqueen(int k)
{   int i;
    if(k==n)
    {	count++;
        printf("第%d种方案\n",count);
        for(i=0;i<=n-1;i++)
            printf("%d ",arr[i]);
        printf("\n");
        return;
    }
    for(i=0;i<n;i++)
    {
       if(check(k,i))
       {
           arr[k]=i;
           nqueen(k+1);
       }
    }
}

int main()
{
    scanf("%d",&n);
	nqueen(0);
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值