Ver Mensaje Individual
  #11 (permalink)  
Antiguo 12/05/2016, 06:44
aguml
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 8 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Bueno, tirando del codigo de y con vuestras explicaciones he llegado a esto:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. /* next lexicographical permutation */
  5. int perm(int *a, int n) {
  6. #   define swap(i, j) {t = a[i]; a[i] = a[j]; a[j] = t;}
  7.     int k, l, t;
  8.  
  9.     /* 1. Find the largest index k such that a[k] < a[k + 1]. If no such
  10.           index exists, the permutation is the last permutation. */
  11.     for (k = n - 1; k && a[k - 1] >= a[k]; k--);
  12.     if (!k--) return 0;
  13.  
  14.     /* 2. Find the largest index l such that a[k] < a[l]. Since k + 1 is
  15.        such an index, l is well defined */
  16.     for (l = n - 1; a[l] <= a[k]; l--);
  17.  
  18.     /* 3. Swap a[k] with a[l] */
  19.     swap(k, l);
  20.  
  21.     /* 4. Reverse the sequence from a[k + 1] to the end */
  22.     for (k++, l = n - 1; l > k; l--, k++)
  23.         swap(k, l);
  24.     return 1;
  25. #   undef swap
  26. }
  27.  
  28. int Diagonal(unsigned *len,int **diagonal,int n)
  29. {
  30.    unsigned j,ok=1;
  31.  
  32.    if(*len == 0){
  33.       *diagonal=(int*)malloc(sizeof(int));
  34.       (*diagonal)[0]=n;
  35.       (*len)++;
  36.    }else{
  37.       for(j=0;j<*len;j++)
  38.          if((*diagonal)[j]==n){
  39.             ok=0;
  40.             break;
  41.          }
  42.       if(ok==1){
  43.          (*len)++;
  44.          *diagonal=(int*)realloc(*diagonal,*len * sizeof(int));
  45.          (*diagonal)[*len-1]=n;
  46.       }
  47.    }
  48.    return ok;
  49. }
  50.  
  51. int esFactible(const int fichas[],unsigned nreinas) {
  52.    int *diagonal_descendente=NULL;
  53.    int *diagonal_ascendente=NULL;
  54.    unsigned i;
  55.    unsigned len_desc=0,len_asc=0;
  56.    int retval=1;
  57.  
  58.    for (i = 0; i < nreinas; ++i) {
  59.       // Si dos valores fila - columna coinciden indican que estamos en
  60.       // la misma diagonal descendente
  61.       if(Diagonal(&len_desc,&diagonal_descendente,i-fichas[i])==0){
  62.          retval=0;
  63.          break;
  64.       }
  65.      
  66.       // Si dos valores fila + columna coinciden indican que estamos en
  67.       // la misma diagonal ascendente
  68.       if(Diagonal(&len_asc,&diagonal_ascendente,i+fichas[i])==0){
  69.          retval=0;
  70.          break;
  71.       }
  72.    }
  73.    free(diagonal_descendente);
  74.    free(diagonal_ascendente);
  75.    diagonal_descendente=NULL;
  76.    diagonal_ascendente=NULL;
  77.      
  78.    // Si no ocurre nada de eso es una solución porque no hay encuentros
  79.    // diagonales y la modelización del espacio de estados evita que haya
  80.    // columnas o filas iguales
  81.    return retval;
  82. }
  83.  
  84. void mostrarAyuda (void)
  85. {
  86.   printf("Instrucciones:\n");
  87.   printf("-------------\n\n");
  88.   printf("Al princicio nos pide el numero de reinas que deseamos colocar en el tablero.\n");
  89.   printf("El numero de reinas sera igual a las dimensiones del tablero, osea que\n");
  90.   printf("el tablero tendra un tamaño de nReinas x nReinas.\n");
  91.   printf("El valor minimo permitido es 4 y el maximo es 10.\n");
  92. }
  93.  
  94. void RepresentarFilaTablero(int size,int posReina)
  95. {
  96.    int i;
  97.  
  98.    for(i=0;i<size;i++)
  99.       if(i!= posReina-1)
  100.          printf("O ");
  101.       else
  102.          printf("X ");
  103. }
  104.  
  105. int main() {
  106.    // Representación del tablero
  107.    // Índice -> Filas -1
  108.    // Valor -> Columnas
  109.    int *reinas;
  110.    unsigned i;
  111.    unsigned nreinas=4;
  112.    int nPermutas=0,nSoluciones=0;
  113.  
  114.    do{
  115.       // Obtener el número de reinas
  116.       printf("Introduce el numero de reinas: ");
  117.       scanf("%d",&nreinas);
  118.  
  119.       if(nreinas <4 || nreinas >10){
  120.          mostrarAyuda();
  121.          system("PAUSE");
  122.          system("CLS");
  123.       }
  124.    }while(nreinas < 4 || nreinas > 10);
  125.  
  126.    // Colocar las reinas en el tablero
  127.    // Crear vector dinámicamente
  128.    reinas = (int*) malloc ( nreinas * sizeof(int) );
  129.  
  130.    // Inicializar vector:
  131.    // (inicialmente, ninguna reina está colocada)
  132.    for (i=0; i<nreinas; i++)
  133.       reinas[i] = i+1;
  134.  
  135.    printf("\n");
  136.  
  137.    // A permutar
  138.    do {
  139.  
  140.       if (esFactible(reinas,nreinas)) {
  141.          printf("SOLUCION (%d):\n",++nSoluciones);
  142.          for (i = 0; i < nreinas; ++i){
  143.             RepresentarFilaTablero(nreinas,reinas[i]);
  144.             printf("  ->  Fila %d\t Columna %d\n",i+1, reinas[i]);
  145.          }
  146.          printf("\n");
  147.          if(nSoluciones % 10 == 0){
  148.             system("PAUSE");
  149.             system("CLS");
  150.          }
  151.       }
  152.       nPermutas++;
  153.    } while(perm(reinas,nreinas));
  154.    printf("En un total de %d combinaciones, se encontraron %d soluciones validas.\n",nPermutas,nSoluciones);
  155.    free(reinas);
  156.    system("PAUSE");
  157.    return 0;
  158. }
Creo que funciona correctamente pero la funcion de permutar la saqué de internet y realmente no tengo ni idea de como funciona dicha funcion pero funciona jajaja. Si pudieran explicarme como funciona ya que con los comentarios que trae no me acabo de enterar.
Y tambien sigo interesado en hacer funcionar sin recursividad el otro codigo que os puse por si podeis ayudarme a arreglarlo. Gracias de antemano por toda la ayuda.

Última edición por aguml; 12/05/2016 a las 07:02