皇后问题

1)8皇后问题:

#include<iostream>

using std::cout;
using std::endl;

#define my_abs(x) ((x)>=0?(x):(-(x)))

const int n=8;
void output(int a[],int n)
{
static int count=1;
cout<<"this is the "<<count<<"th answer"<<endl<<endl;
for (int i=1;i<=n;i++)
cout<<i<<" "<<a[i]<<endl;
count++;
}


bool constraint(int a[],int k)
{
for(int i=1;i<k;i++)
	if(my_abs(k-i)==my_abs(a[k]-a[i])||(a[i]==a[k]))
	return false;
return true;
}

void back_track(int a[],int i)
{
if(i>n)
{
output(a,n);
}
else
{
for(int j=1;j<=n;j++)
	{
	a[i]=j;
	if(constraint(a,i))
		back_track(a,i+1);
	}
}
}

int main()
{

int *a=new int[n+1];
back_track(a,1);
delete []a;
return 0;
}

2)扩充:

在一个m*n的棋盘,放置k个棋子,使得这k个棋子既不在同一行也不在同一列,并且不在同一对角线上(包括主对角线和副对角线)。问:有多少种放置方法?


分析:

数组a[i](1=<i<=m)表示第i行放置在值为a[i]的位置。比如a[1]=5,表示第1行在第5个位置放了棋子。(注意:数组第第0个单元未用)。

如果k<m的话,说明有的行(设第i行)没有放置棋子,则a[i]=0。


#include<iostream>

using std::cout;
using std::endl;

#define my_abs(x) ((x)>=0?(x):(-(x)))

//const int m=8;
//const int n=8;
//const int k=8;
int m,n,k;

static int sum=0;

void output(int a[],int n)
{
int count=0;
for (int i=1;i<=n;i++)

//如果a[i]不等于0,表明此行放置了棋子
if(a[i])                                             
	count++;

//统计放置了棋子的行数,如果等于k,说明符合要求,总数加1。大于或小于k都不符合。
if(count==k)
	sum++;
}


bool constraint(int a[],int k)
{
for(int i=1;i<k;i++)
{
//a[i]  a[k]有一个为0都不会冲突
	if(!a[i]||!a[k])
	continue;
	if(my_abs(k-i)==my_abs(a[k]-a[i])||(a[i]==a[k]))
	return false;
}
return true;
}

void back_track(int a[],int i)
{
if(i>m)
{
output(a,m);
}
else
{

//j=0表示该行没有放置棋子。
for(int j=0;j<=n;j++)   
	{
	a[i]=j;
	if(constraint(a,i))
		back_track(a,i+1);
	}
}
}

int main()
{
cout<<"input m , n , k"<<endl;
std::cin>>m>>n>>k;
int *a=new int[m+1];
back_track(a,1);
cout<<"there are "<<sum<<" kinds of methods"<<endl;
delete []a;
return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值