Descripción del problema
Encuentre una disposición de 0 ~ N-1 (es decir, cada número solo puede aparecer una vez), dadas las restricciones (una tabla de N * N, 1 o 0 en la fila i y columna j, expresada como j-1 El número no puede aparecer después del número i-1, y asegúrese de que la fila i-ésima y la columna i-ésima sean 0). Trate esta disposición como un número natural y encuentre la disposición K en orden ascendente.
Tamaño de datos y acuerdo
N <= 10, K <= 500000
Formato de entrada
La primera línea es N y K, las siguientes N líneas, N números en cada línea, 0 significa no, 1 significa sí
Formato de salida
El arreglo solicitado
Entrada de muestra
3 2
0 1 1
1 0 0
0 1 0
Salida de muestra
1 0 2
Explicación:
Para el caso de N = 3 sin restricciones
Primero: 0 1 2
Segundo: 0 2 1
Tercero: 1 0 2
Cuarto: 1 2 0
Quinto: 2 0 1
Sexto: 2 1 0
limitaciones el título dado no pueden aparecer debido a la parte de atrás 1 2, 0 2 no puede aparecer detrás de
la primera 021
en segundo lugar: 102
tercero: 210
de referencia de https: //blog.csdn. net / weixin_44778155 / article / details / 104672498 Esta
pregunta es difícil de entender, así que déjenme explicarla brevemente.
Primero, generamos una disposición completa de 0 ~ n-1, por ejemplo, cuando n = 3, la disposición completa está en orden:
Primero: 0 1 2
Segundo: 0 2 1
Tercero: 1 0 2
Cuarto: 1 2 0
Quinto: 2 0 1
Sexto: 2 1 0
Luego damos un límite, este límite se pasa un n * Dada la matriz de n, abrimos una matriz bidimensional vis [] [] para registrar esta matriz.
En esta matriz, el 0 en la diagonal i = j de arriba a la izquierda a la derecha es inútil, no necesitamos mirarlo.
Solo vemos si hay 0s en otras posiciones, en el ejemplo, es vis [1] [2] = 0, vis [2] [0] = 0
Es decir, 2 no puede ser seguido de cerca por 1, con algunos números intermedios, y luego 2 es posible después de 1. Por lo tanto, la primera y la cuarta de las seis permutaciones anteriores no cumplen los requisitos y se eliminan.
Entonces 0 no puede seguir a 2 de cerca . El quinto anterior se elimina.
Entonces el resto de la permutación es:
Primero: 0 2 1
Segundo: 1 0 2
Tercero: 2 1 0
Luego muestree k = 2, así que envíe el segundo arreglo completo 1 0 2
y luego este código es fácil de entender.
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, k, cnt; 4 int a[20]; 5 int vis[20][20]; 6 bool check() { //check函数用于判断当前这个全排列是否符合题意 7 for (int i = 1; i < n; i++) { //遍历这个全排列,看看是否存在某个数不能紧贴在某个数后面的情况 8 if (vis[a[i - 1]][a[i]] == 0) { 9 return false; 10 } 11 } 12 return true; 13 } 14 int main() { 15 cin >> n >> k; 16 for (int i = 0; i < n; i++) { 17 a[i] = i; //生成0~n-1的序列 18 } 19 for (int i = 0; i < n; i++) { //输入限制 20 for (int j = 0; j < n; j++) { 21 cin >> vis[i][j]; 22 } 23 } 24 do { 25 if (check()) { //判断这个序列是否符合要求 26 if (++cnt == k) { //若符合要求,++cnt。求到第k个符合条件的全排列的话,break 27 break; 28 } 29 } 30 } while (next_permutation(a, a + n)); 31 for (int i = 0; i < n; i++) { //输出这个全排列 32 cout << a[i] << " "; 33 } 34 cout << endl; 35 return 0; 36 }