Tarea de diseño de ruta de superestrella de la Universidad de Jilin 08 Ocho reinas Soluciones esencialmente diferentes

8 soluciones esencialmente diferentes de Queen

El código está escrito por mí mismo y las ideas están escritas debajo del código. Espero discutir contigo ~

Título: La esencia de las ocho reinas

Descripción del Título:

Como se mencionó en la pregunta anterior, cuando N = 8, hay 92 posibilidades. Si elimina el juego simétrico de arriba a abajo, simétrico de izquierda a derecha, el juego simétrico diagonal principal y viceversa y el juego repetido después de la rotación, hay 12 juegos completamente diferentes. Escribe un programa para generar estos 12 juegos de ajedrez.

entrar:

No

Salida:

Un total de 12 líneas, cada línea produce 1 juego,

Por ejemplo, la primera línea da como resultado No1: 1 5 8 6 3 7 2 4 (los dos puntos son dos puntos occidentales sin caracteres adicionales antes y después de los dos puntos, hay un espacio occidental después de cada número después de los dos puntos),

Entre ellos, el No1 indica que este es el primer juego; la secuencia numérica posterior indica la posición de las ocho reinas, el valor en sí indica las coordenadas de la fila de una determinada reina en el tablero de ajedrez y la posición del valor indica las coordenadas de la columna de la reina (> 0), por ejemplo, un número 5 se ubica en la segunda posición de la secuencia, lo que indica que hay una reina en la quinta fila y la segunda columna en el tablero de ajedrez; el número 4 se ubica en la octava posición en la secuencia, lo que indica que hay una reina en la cuarta fila y la octava columna en el tablero de ajedrez, por lo que estos 8 números describen un juego de ajedrez. El orden de salida de las 12 partidas de ajedrez: orden del diccionario (consulte el ejemplo).

Ejemplo:

Entrada: (Ninguna)
Salida:
No1: 1 5 8 6 3 7 2 4
No2: 1 6 8 3 7 4 2 5
…… (Aquí se omiten 10 líneas, indicando los juegos No3 a No12 respectivamente)

#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;
}

La idea de este método de solución es aproximadamente la siguiente:
1. Use DFS para encontrar cada conjunto de soluciones de las siguientes ocho reinas y guárdelas en la matriz bidimensional res1.
2.Función de verificación personalizada, el parámetro son dos matrices de un bit (cada una contiene 1 conjunto de soluciones), la función es verificar si la esencia de las soluciones almacenadas en estas dos matrices de un bit es la misma, los mismos retornos 0, pero el diferente devuelve 1.
3. Recorra la matriz res1 que guarda 92 conjuntos de soluciones y verifique cada conjunto de soluciones con las soluciones actualmente guardadas en la matriz res. Si check = 1 (esencialmente diferente), guarde el conjunto de soluciones en el siguiente elemento de la matriz. res.
4. Genere cada conjunto de soluciones en res.

Un novato, el código es solo para comunicación. Todavía hay muchas deficiencias, si alguien sabe qué se puede mejorar, espero que me lo digan, ¡gracias por la ayuda!

Supongo que te gusta

Origin blog.csdn.net/u010656213/article/details/111825670
Recomendado
Clasificación