Jilin University Superstar Path Design Homework 08 Eight Queens Essentially Different Solutions

8 Queen’s Essentially Different Solutions

The code is written by myself, and the ideas are written below the code. I hope to discuss with you~

Title: The essence of the eight queens

Title description:

As mentioned in the previous question, when N=8, there are 92 possibilities. If you remove the up-and-down symmetrical, left-right symmetrical game, the main and vice diagonal symmetrical game and the repeated game after the rotation, there are 12 completely different games. Write a program to output these 12 chess games.

enter:

no

Output:

A total of 12 lines, each line outputs 1 game,

For example, the first line outputs No1: 1 5 8 6 3 7 2 4 (the colon is a Western colon with no extra characters before and after the colon, there is a Western space after each number after the colon),

Among them, No1 indicates that this is the first game; the subsequent number sequence indicates the position of the eight queens, the value itself indicates the row coordinates of a certain queen on the chessboard, and the position of the value indicates the column coordinates of the queen (>0), for example, a number 5 is located in the second position of the sequence, indicating that there is a queen in the fifth row and the second column on the chessboard; the number 4 is located in the eighth position in the sequence, indicating that there is a queen in the fourth row and the eighth column on the chessboard, so these 8 numbers Describes a chess game. The output order of the 12 chess games: dictionary order (refer to the sample).

Example:

Input: (None)
Output:
No1: 1 5 8 6 3 7 2 4
No2: 1 6 8 3 7 4 2 5
…… (10 lines are omitted here, indicating games No3 to No12 respectively)

#include<stdio.h>
#define N 8
int m = 0, res[92][8] = {
    
    0}, res1[92][8] = {
    
     0 }, B[N][N] = {
    
     0 }, a[N] = {
    
     0 }, j = 0;
   int check(int*res1i,int*resi) {
    
    //检查两组结果是否存在这些问题
		int f = 0;
		for (int i = 0; i < 8; i++) 
			if (res1i[i] != resi[7 - i]) {
    
     f = 1; break; };//上下对称
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++) 
		if (res1i[i] + resi[i] != 7) {
    
     f = 1; break; };//左右对称
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++) 
		if (resi[res1i[i]] != i) {
    
     f = 1; break; };//主对角线
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++) 
		if (resi[7 - res1i[i]] != 7 - i) {
    
     f = 1; break; };//副对角线
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++)
			if (resi[7 - i] != 7 - res1i[i]) {
    
     f = 1; break; };//旋转180
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++)
			if (resi[res1i[i]]!=7-i) {
    
     f = 1; break; };//旋转-90
		if (f == 0) return f;
		f = 0;
		for (int i = 0; i < 8; i++)
			if (resi[7-res1i[i]]!=i) {
    
     f = 1; break; };//旋转90
		if (f == 0) return f;
	return 1;
}
void DFS(int r) {
    
    
	if (j == r) {
    
    //终点
		for (int i = 0; i < 8; i++) {
    
    
			res1[m][i] = a[i];
		}
		m++;
		return;
	}
	for (int k = 0; k < r; k++) {
    
    
		if (B[j][k] == 0) {
    
     //尝试成功
			a[j] = k;//printf("a[%d]已装填=%d\n", j , a[j]);
			for (int i = 0; i < r; i++)
				B[i][k]++;
			for (int i = 1; k - i >= 0 && j + i < r; i++)
				B[j + i][k - i]++;
			for (int i = 1; j + i < r && k + i < r; i++)
				B[j + i][k + i]++;
			j++;//j指向下一个数
			DFS(r);
			/*回复到未填状态*/
			j--;//返回,准备重新填该数
			for (int i = 0; i < r; i++)
				B[i][k]--;
			for (int i = 1; k - i >= 0 && j + i < r; i++)
				B[j + i][k - i]--;
			for (int i = 1; j + i < r && k + i < r; i++)
				B[j + i][k + i]--;
		}
	}
}
int main() {
    
    
	DFS(8);
	m = 0;
	int f ,l;
	for (l = 0; l < 92; l++) {
    
    
		for (int k = 0; k < 12; k++) {
    
    
			f = 1;
			if (check(res1[l], res[k]) == 0) {
    
    
				f = 0;
				break;
			}
		}
		if (f) {
    
    //赋值
			for (int i = 0; i < 8; i++) 
				res[m][i] = res1[l][i];
			m++;
		}
		}
	for (l = 0; l < 11; l++) {
    
    
		printf("No%d:", l+1);
		for (int k = 0; k < 8; k++)
			printf("%d ", res[l][k]+1);
		printf("\n");
	}
	printf("No%d:", l + 1);
	for (int k = 0; k < 8; k++)
		printf("%d ", res[l][k]+1);
	return 0;
}

The idea of ​​this solution is roughly as follows:
1. Use DFS to find each set of solutions for the next eight queens, and save them in a two-dimensional array res1.
2. Custom check function, the parameter is two one-bit arrays (each one holds 1 set of solutions), the function is to check whether the essence of the solutions stored in these two one-bit arrays is the same, the same returns 0, but the different returns 1.
3. Traverse the array res1 that saves 92 sets of solutions, and check each set of solutions with the solutions currently saved in the array res. If check=1 (essentially different), save the set of solutions in the next item of the array res .
4. Output each set of solutions in res.

A newbie, the code is for communication only. There are still many shortcomings. If someone knows what can be improved, I hope they can tell me, thank you for your help!

Guess you like

Origin blog.csdn.net/u010656213/article/details/111825670