皇后问题

来源:互联网 发布:网络贷款需要什么条件 编辑:程序博客网 时间:2024/04/28 01:38

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;}



原创粉丝点击