题目编号:Exp08-Basic03
题目名称:八皇后本质不同的解
题目描述:
如上题所述,当N=8时,一共有92种可能。如果去除其中上下对称、左右对称棋局、主副对角线对称棋局和旋转后重复棋局,则有12种完全不同的棋局。编写程序,输出这12种棋局。
输入:
无
输出:
共12行,每行输出1种棋局,
例如,第一行输出 No1:1 5 8 6 3 7 2 4(冒号为西文冒号且前后无多余字符,冒号后的每个数字后均有一个西文空格),
其中No1 表示这是第1种棋局;后续数字序列表示八皇后所在位置,数值本身表示某个皇后在棋盘上的行坐标,该数值所在位置表示该皇后的列坐标(>0),例如,数字5位于序列的第2位,表示棋盘上第5行第2列有一个皇后;数字4位于序列的第8位,表示棋盘上第4行第8列有一个皇后,由此,这8个数字描述了一种棋局。12种棋局的输出顺序:字典序(参考样例)。
样例:
输入:(无)
输出: No1:1 5 8 6 3 7 2 4
No2:1 6 8 3 7 4 2 5
……(此处省略10行,分别表示No3至No12棋局)
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
bool decision(int a[],int n) ;
void DFS(int n);
int a[8];
int last [92][9];
int flag = 0;
int cnt = 0;
int sum;
int i ;
int j ;
bool check1(int i,int j){
for(int k = 0;k<8;k++){
if(last[i][k]!=last[j][7-k]){
return false;
}
}
return true;
}//左右
bool check2(int i,int j){
for(int k = 0;k<8;k++){
if(last[i][k]+last[j][k]!=7){
return false;
}
}
return true;
}//上下
bool check3(int i,int j){
for(int k = 0;k<8;k++){
if(last[j][7-last[i][k]]!=k){
return false;
}
}
return true;
}
bool check4(int i,int j){
for(int k = 0;k<8;k++){
if(last[j][last[i][k]]!=k){
return false;
}
}
return true;
}
bool check5(int i,int j){
for(int k = 0;k<8;k++){
if(last[j][last[i][k]]!=7-k){
return false;
}
}
return true;
}
bool check6(int i,int j){
for(int k = 0;k<8;k++){
if(last[j][7-last[i][k]]!=7-k){
return false;
}
}
return true;
}
bool check7(int i,int j){
for(int k = 0;k<8;k++){
if(last[i][k]!=7-last[j][7-k]){
return false;
}
}
return true;
}//中心对称
int main(){
DFS(8);
for(int i = 0;i<92-1;i++){
for(int j = i+1;j<92;j++){
if(check1(i,j)||
check2(i,j)||
check3(i,j)||
check4(i,j)||
check5(i,j)||
check6(i,j)||
check7(i,j)){
last[j][8]=9999;
}
}
}
int count = 1;
for(int i = 0;i<92;i++){
if(last[i][8]!=9999){
printf("No%d:",count);
for(int j =0;j<8;j++){
printf("%d ",last[i][j]+1);
}
printf("\n");
count++;
}
}
return 0;
}
void DFS(int n) {
if(n==0){
for(int i=0;i<8;i++){
last[cnt][i]=a[i];
}
cnt++;
return;
}
for(int i=0;i<8;i++){
a[flag]=i;
flag++;
if((n-1>=0)&&decision(a,flag)){
DFS(n-1);
}
flag--;
}
}
bool decision(int a[],int n) {
for(i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if((a[j]-a[i]==i-j)||(a[j]-a[i]==j-i)){
return false;
}
if(a[i]==a[j]){
return false;
}
}
}
return true;
}