西安政府网站开发公司cms建站系统
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
输入
一个整数n( 1 < = n < = 10 )
输出
每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”
样例输入
4
样例输出
2 4 1 3
3 1 4 2
分析:可以用生成全排列的方法表示皇后的坐标,其中第一个坐标用存储数组的位置下标代替,生成的全排列就是皇后的第二个坐标。显然第一个坐标和第二个坐标都不会重复,即皇后不会处于同一排或者同一列上,因此只需要判断是否处在同一斜线上。这样在生成全排列的时候就可以提前去掉不可能的组合,能够生成的排列一定是符合要求的。
如果两个皇后处于同一斜线上,这条斜线的斜率绝对值一定为1,即两个皇后的横坐标之差等于纵坐标之差。前面提到横坐标是存储数组的下标,纵坐标是生成的排列,这样相减后取绝对值进行比较即可。
#include<algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
#define ll long long
#define INF 0x3f3f3f3f
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,a) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<endl
using namespace std;void getans(int n,int index,int *num,int *flag,int &ans)
{if(index==n){ans++;for(int i=0;i<n;++i)i==0?printf("%d",num[i]):printf(" %d",num[i]);printf("\n");return;}for(int i=1;i<=n;++i){if(flag[i]==0){int f=1;for(int j=0;j<index;++j){if((int)fabs(num[j]-i)==(int)fabs(index-j)){f=0;break;}}if(f){num[index]=i,flag[i]=1;getans(n,index+1,num,flag,ans);flag[i]=0;}}}return;
}int main(void)
{#ifdef testfreopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);clock_t start=clock();#endif //testint n;while(~scanf("%d",&n)){if(n<=3){printf("no solute!\n");continue;}int num[n+5]={0},flag[n+5]={0};int ans=0;getans(n,0,num,flag,ans);}#ifdef testclockid_t end=clock();double endtime=(double)(end-start)/CLOCKS_PER_SEC;printf("\n\n\n\n\n");cout<<"Total time:"<<endtime<<"s"<<endl; //s为单位cout<<"Total time:"<<endtime*1000<<"ms"<<endl; //ms为单位#endif //testreturn 0;
}