吉林大学超星慕课高级语言程序设计课后作业(2023版)实验09 八皇后本质不同的解

题目编号: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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值