在国际象棋棋盘上:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入格式:
输入共n+1行。第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出格式:
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
输入样例:
2
1
92
输出样例:
15863724
84136275
题目分析:
8*8个方格中,每一颗棋子同一行同一列同一斜线上不存在棋子,但一行一行循环判断过于复杂,时间复杂度也高,所以我们可以采用列举出1-8所有的全排列,再筛选的暴力解法
void f(int a[],int m,int e[]){
int i,t;
static int const_=0;
int bool_=1; //设bool_来记录是否上一个判断通过
static int count=0;
int rol[8];
if(m==7){
for(int i=0;i<8;i++){ //判断斜线上是否有棋子
for(int j=i+1;j<8;j++){
if(a[i]+i==a[j]+j || a[i]-i==a[j]-j){
bool_=0; //若有bool_==0
}
}
}
定义一个判断函数,为什么判断条件是m==7一会儿再解释,第一个循环判断斜线上是否已经有棋子,a[i]存储的是每一行存在的棋子的列坐标,在同一斜线上,横坐标纵坐标和相等,所以可以判断是否再同一斜线上
if(bool_==1){ //判断第一个判断条件是否通过
for(int i=0;i<8;i++){
e[count]+=a[i];
e[count]*=10;
}e[count]/=10;
count++;
}
由于题目让我们从小到大比较串后输出,这里是将满足条件的全排列变成一个八位数存储进e数组以便于后面从小到大筛选,以及选择要输出的串。
for(i=m;i<8;i++){
t=a[m];a[m]=a[i];a[i]=t;
f(a,m+1,e);
t=a[m];a[m]=a[i];a[i]=t;
}
以上是利用函数递归进行全排列,m每进行一次排列值就会加一,当m=7时代表全排列结束,得到一个排列后的数,然后我们就可以进行前面所提到的判断全排列是否符合八皇后标准。
int main()
{
int e[92]={0};
int a[8]={1,2,3,4,5,6,7,8};
int n,m=0,t;
int b[92],c[92];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
f(a,m,e); //调用八皇后函数
for(int i=0;i<91;i++){ //对八皇后数列进行排序
for(int j=0;j<91-i;j++){
if(e[j]>e[j+1]){
t=e[j+1];e[j+1]=e[j];e[j]=t;
}
}
}
for(int i=0;i<n;i++){
t=b[i]-1; //根据输入的值来输出所需要的数列
printf("%d",e[t]);
printf("\n");
}
return 0;
}
这里是主函数,比起上面的函数较为简单,这里就不过多赘述。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void f(int a[],int m,int e[]);
void f(int a[],int m,int e[]){
int i,t;
static int const_=0;
int bool_=1;
static int count=0;
int rol[8];
if(m==7){
for(int i=0;i<8;i++){
for(int j=i+1;j<8;j++){
if(a[i]+i==a[j]+j || a[i]-i==a[j]-j){
bool_=0;
}
}
}
if(bool_==1){
for(int i=0;i<8;i++){
e[count]+=a[i];
e[count]*=10;
}e[count]/=10;
count++;
}
}
for(i=m;i<8;i++){
t=a[m];a[m]=a[i];a[i]=t;
f(a,m+1,e);
t=a[m];a[m]=a[i];a[i]=t;
}
}
int main()
{
int e[92]={0};
int a[8]={1,2,3,4,5,6,7,8};
int n,m=0,t;
int b[92],c[92];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
f(a,m,e);
for(int i=0;i<91;i++){
for(int j=0;j<91-i;j++){
if(e[j]>e[j+1]){
t=e[j+1];e[j+1]=e[j];e[j]=t;
}
}
}
for(int i=0;i<n;i++){
t=b[i]-1;
printf("%d",e[t]);
printf("\n");
}
return 0;
}
这里是完整的代码,仅供参考