Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Saber todas las combinaciones posibles de un tablero

Estas en el tema de Saber todas las combinaciones posibles de un tablero en el foro de C/C++ en Foros del Web. Hola amigos, hoy he estado ayudando en la tarea de mates a la peque y la verdad es que el ejercicio no lo entiendo ni ...
  #1 (permalink)  
Antiguo 11/05/2016, 09:28
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Saber todas las combinaciones posibles de un tablero

Hola amigos, hoy he estado ayudando en la tarea de mates a la peque y la verdad es que el ejercicio no lo entiendo ni yo pero de él me ha surgido una duda. El ejercicio decía algo asi:
Cita:
Pablo tiene 4 fichas y las quiere colocar en una cuadricula de 4 filas por 4 columnas de manera que con coincidan en fila, ni en columna, ni en diagonal. Dibuja todas las combinaciones posibles.
Yo como un tonto he dibujado la cuadricula y con 4 garbanzos he intentado colocar las fichas de manera que ninguna coincidiera con otra en la misma fila, o en la misma columna, o en la misma diagonal. Deduje que es imposible o al menos yo no vi la manera. Entonces se me ocurrió que quizás se refiere a que no pueden estar todas alineadas ni en una fila, ni en una columna, ni en una diagonal. Es poco probable que sea este caso porque es una niña de 9 años y creo que podrían ser muchas combinaciones así que que ponga lo que le parezca y ya veremos cuando lo corrijan pero este último planteamiento que he dado me gustaría saber como resolverlo en C. ¿alguien sabría explicar como hay que plantear esto o que formula matemática se usa o algo?
  #2 (permalink)  
Antiguo 11/05/2016, 11:39
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Saber todas las combinaciones posibles de un tablero

Para resolver problemas de este tipo hay muchas técnicas variadas de búsqueda en espacio de estados que dan solución al problema (búsquedas en anchura, profundidad, algoritmos genéticos) o técnicas algorítmicas de backtracking o branch & bound suelen ser útiles. Probablemente backtracking sea la más apropiada para el problema.

No obstante, el número de tableros posibles para 4 fichas si consideramos una representación con un vector de 4 enteros en el que el índice es la fila y el valor es la columna y en los valores aparece cada valor del 1 al 4 una única vez se reduce a comprobar todas las permutaciones de esos cuatro números y determinar cuáles son factibles, y 4! = 4 * 3 * 2 = 24 tableros se comprueba en un momentillo. Por tanto hacerlo por fuerza bruta no es ningún problema. En C++:

Código C++:
Ver original
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <set>
  4. #include <tuple>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. bool esFactible(const vector<int>& fichas) {
  10.     set<int> diagonal_descendente;
  11.     set<int> diagonal_ascendente;
  12.     bool unico = true;
  13.     for (unsigned i = 0; i < fichas.size(); ++i) {
  14.         // Si dos valores fila - columna coinciden indican que estamos en
  15.         // la misma diagonal descendente
  16.         tie(ignore, unico) =diagonal_descendente.insert(i-fichas[i]);
  17.         if (!unico)
  18.             return false;
  19.  
  20.         // Si dos valores fila + columna coinciden indican que estamos en
  21.         // la misma diagonal ascendente
  22.         tie(ignore, unico) = diagonal_ascendente.insert(i+fichas[i]);
  23.         if (!unico)
  24.             return false;
  25.     }
  26.  
  27.     // Si no ocurre nada de eso es una solución porque no hay encuentros
  28.     // diagonales y la modelización del espacio de estados evita que haya
  29.     // columnas o filas iguales
  30.     return true;
  31. }
  32.  
  33. int main() {
  34.     // Representación del tablero
  35.     // Índice -> Filas -1
  36.     // Valor -> Columnas
  37.     vector<int> fichas {1, 2, 3, 4};
  38.  
  39.     // A permutar
  40.     do {
  41.         if (esFactible(fichas)) {
  42.             cout << "SOLUCION" << endl;
  43.             for (unsigned i = 0; i < fichas.size(); ++i)
  44.                 cout << "Fila " << i+1 << "\t Columna" << fichas[i] << endl;
  45.             cout << endl << endl;
  46.         }
  47.     } while (next_permutation(fichas.begin(),fichas.end()));
  48.  
  49. }
Que me devuelve como solución dos únicos tableros que cumplen eso si no lo he hecho mal que creo que no.

Fila 1 Columna2
Fila 2 Columna4
Fila 3 Columna1
Fila 4 Columna3


SOLUCION
Fila 1 Columna3
Fila 2 Columna1
Fila 3 Columna4
Fila 4 Columna2

Hay un problema muy similar a este que es el problema de las 8 reinas y que se resolvería de la misma manera (eso sí la fuerza bruta cuanto más grande es el tablero menos recomendable). Infórmate sobre éstos que te he comentado y te dará para rato y una manera de encontrar la solución más apropiada que comprobarlo todo y aunque este problema haya sido resuelto aquí con esta fuerza bruta cutre la búsqueda en el espacio de estados en un tema denso e interesante si te gustan este tipo de problemas.
  #3 (permalink)  
Antiguo 11/05/2016, 14:48
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Cita:
y 4! = 4 * 3 * 2 = 24 tableros
No entiendo eso que dices hay..
Por otro lado lo pedía en C porque de C++ no entiendo tanto y por ejemplo eso que haces aqui:

Código PHP:
    set<intdiagonal_descendente;
    
set<intdiagonal_ascendente;
    
bool unico true;
    for (
unsigned i 0fichas.size(); ++i) {
        
// Si dos valores fila - columna coinciden indican que estamos en
        // la misma diagonal descendente
        
tie(ignoreunico) =diagonal_descendente.insert(i-fichas[i]);
        if (!
unico)
            return 
false;
 
        
// Si dos valores fila + columna coinciden indican que estamos en
        // la misma diagonal ascendente
        
tie(ignoreunico) = diagonal_ascendente.insert(i+fichas[i]);
        if (!
unico)
            return 
false;
    } 
SI como dices que lo de las ocho reinas es igual, voy a buscar info por la red a ver si encuentro algo donde se explique con mucha claridad.
  #4 (permalink)  
Antiguo 11/05/2016, 15:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Saber todas las combinaciones posibles de un tablero

4! Lo dice porque la primera ficha puede estar en cualquiera de las 4 filas, mientras que la segunda ficha puede estar únicamente en tres filas (no puede coincidir con la fila ocupada por la primera ficha). Con el mismo planteamiento se deduce que la tercera ficha únicamente puede estar colocada en 2 posibles filas y la cuarta ya no tiene elección.

Estas condiciones te dan 4*3*2*1=4!=24 posibles combinaciones.

Si tuviese en cuenta a la vez las columnas entonces el número de posibles combinaciones crece hasta las 576 combinaciones, 24^2.

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #5 (permalink)  
Antiguo 11/05/2016, 15:17
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Saber todas las combinaciones posibles de un tablero

Perdona, no toco mucho el C sin el ++, jeje.
el 4! hace referencia 4 factorial que es el número de permutaciones sin repeticiones posibles sin repetición de {1,2,3,4}, como te ha indicado eferion

El esquema de fuerza bruta usado es el siguiente:

Para cada permutación de {1,2,3,4}
Si es factible, lo muestro como solución por pantalla.

Una permutación es factible si: (Esto es fácil de comprobar con papel y boli)
La resta de su fila menos su columna es única en el array de diagonales descendentes.
La suma de su fila más su columna es única en el array de diagonales ascedentes.

Puesto que los índices del array indican los valores de la fila y son únicos y del 1 al 4 nunca va a haber dos fichas en la misma fila.

Puesto que los valores para cada permutación son siempre los mismos que los iniciales pero en orden diferente, van de 1 a 4 y son únicos, los valores del array representan las columnas y son únicos.

¿Así lo entiendes mejor?

Saludos.
  #6 (permalink)  
Antiguo 11/05/2016, 16:42
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Lo del factorial no me acabo de enterar pero eso es porque nunca los di en el cole (o falte ese dia) jejeje. La verdad es que ahí estoy muy perdido aunque que encantan las matemáticas.
Lo otro ya me ha quedado claro.

A ver si me entero, el factorial es el producto de todos los valores enteros desde 1 a n y como aquí va de 1 a 4 es 1*2*3*4=24.
Eso sería solo para las filas pero si quisiera realmente saber cuantas combinaciones realmente hay serian:
(!n)^2
Cómo hay 4 filas y cuatro columnas y dos diagonales tendríamos ya de entrada un descarte de 10 combinaciones.
¿El truco aquí está en que sólo usamos un array unidmensional y con eso se reducen las posibles combinaciones de (!n)^2 a !n ?
Mañana si puedo lo intentaré hacer en c a ver que sale. Ya vi el de las 8 reinas en c pero usando recursividad y la verdad es que la recursividad y yo nos llevamos muy mal así que quiero codearlo sin ella jejeje.

Última edición por aguml; 11/05/2016 a las 16:56
  #7 (permalink)  
Antiguo 12/05/2016, 02:23
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Bueno amigos, he encontrado este código en C que usa recursividad: http://elvex.ugr.es/decsai/c/problemas/reinas/reinas2.c
Estoy intentando pasarlo a no recursivo y me tiene loco porque no veo el modo de hacerlo. El caso es que, como dije, la recursividad y yo somos enemigos declarados y me pierdo cuando intento entender una funcion recursiva por muy sencilla que sea jajaja. Aqui está lo que llevo:
Código C:
Ver original
  1. // Problema de las N reinas
  2. // ------------------------
  3.  
  4. // Algoritmo recursivo
  5. //
  6. // 0. Obviamente, colocaremos una reina en cada fila
  7. //
  8. // 1. Se coloca una reina en una casilla de su fila y,
  9. //    a continuación, se intentan colocar las reinas restantes.
  10. //
  11. // 2. Si las demás reinas no se pueden colocar con éxito,
  12. //    probamos a colocar la reina actual en otra columna.
  13. //
  14. // Caso base: Cuando no quedan reinas por colocar.
  15.  
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19.  
  20. // Constantes simbólicas
  21.  
  22. #define TRUE  1
  23. #define FALSE 0
  24.  
  25.  
  26. // Comprobar si una reina está bien colocada
  27. // -----------------------------------------
  28. // La reina de la fila i está bien colocada si no está
  29. // en la columna ni en la misma diagonal que cualquiera
  30. // de las reinas de las filas anteriores
  31. //
  32. // Parámetros
  33. //   fila   - Fila de la reina cuya posición queremos validar
  34. //   reinas - Vector con las posiciones de las reinas
  35. //   n      - Número de reinas
  36.  
  37.  
  38. int comprobar (int fila, int reinas[], int n)
  39. {
  40.   int i;
  41.  
  42.   for (i=0; i<fila; i++)
  43.       if (  ( reinas[i]==reinas[fila] )                      // Misma columna
  44.          || ( abs(fila-i) == abs(reinas[fila]-reinas[i]) ) ) // Misma diagonal
  45.          return FALSE;
  46.  
  47.   return TRUE;
  48. }
  49.  
  50.  
  51. // Mostrar el tablero con las reinas
  52. // ---------------------------------
  53. // Parámetros:
  54. //   reinas - Vector con las posiciones de las distintas reinas
  55. //   n      - Número de reinas
  56.  
  57. void mostrarTablero (int reinas[], int n)
  58. {
  59.   int i,j;
  60.  
  61.   for (i=0; i<n; i++) {
  62.  
  63.       for (j=0; j<n; j++) {
  64.  
  65.           if (reinas[i]==j)
  66.              printf("#");
  67.           else
  68.              printf("-");
  69.       }
  70.  
  71.       printf(" %d %d\n",i,reinas[i]);
  72.   }
  73.  
  74.   printf("\n");
  75. }
  76.  
  77.  
  78. // Colocación de una reina
  79. // -----------------------
  80. // Parámetros
  81. //   fila   - Fila de la reina que queremos colocar
  82. //   reinas - Vector con las posiciones de las reinas
  83. //   n      - Número de reinas
  84.  
  85. int colocarReina (int fila, int reinas[], int n)
  86. {
  87.   int ok = FALSE;
  88.  
  89.   if (fila<n) {
  90.  
  91.      // Quedan reinas por colocar
  92.  
  93.          // Comprobamos si la posición
  94.          // de la reina actual es válida
  95.  
  96.          if (comprobar(fila,reinas,n)) {
  97.  
  98.             // Si es así, intentamos colocar
  99.             // las reinas restantes
  100.             ok = TRUE;
  101.          }
  102.  
  103.   } else {
  104.  
  105.      // No quedan reinas por colocar (solución)
  106.  
  107.      mostrarTablero(reinas,n);
  108.   }
  109.  
  110.   return ok;
  111. }
  112.  
  113.  
  114.  
  115. // Mostrar información acerca del uso del programa
  116. // -----------------------------------------------
  117. // Parámetro:
  118. //   programa - Nombre del programa
  119.  
  120. void mostrarAyuda (char *programa)
  121. {
  122.   printf("Instrucciones:\n");
  123.   printf("-------------\n\n");
  124.   printf("Al princicio nos pide el numero de reinas que deseamos colocar en el tablero.\n");
  125.   printf("El numero de reinas sera igual a las dimensiones del tablero, osea que\n");
  126.   printf("el tablero tendra un tamaño de nReinas x nReinas.\n");
  127.   printf("El valor minimo permitido es 4 y el maximo es 10.\n");
  128. }
  129.  
  130. // Programa principal
  131. // ------------------
  132.  
  133. int main (int argc, char *argv[])
  134. {
  135.   int *reinas;  // Vector con las posiciones de las reinas de cada fila
  136.   int nreinas;  // Número de reinas
  137.   int i;        // Contador
  138.   int fila;
  139.   int nposibles,probados=0;
  140.  
  141.   // Obtener el número de reinas
  142.   printf("Introduce el numero de reinas: ");
  143.   scanf("%d",&nreinas);
  144.  
  145.   if(nreinas >=4 && nreinas <=10){
  146.       // Colocar las reinas en el tablero
  147.  
  148.       // Crear vector dinámicamente
  149.       reinas = (int*) malloc ( nreinas*sizeof(int) );
  150.  
  151.       // Inicializar vector:
  152.       // (inicialmente, ninguna reina está colocada)
  153.       for (i=0; i<nreinas; i++)
  154.           reinas[i] = -1;
  155.  
  156.       //Obtener el numero de combinaciones posibles
  157.       for(i=1,nposibles=1;i<=nreinas;i++)
  158.          nposibles *= i;
  159.  
  160.       // Colocar reinas
  161.       do{
  162.          fila=0;
  163.          for (reinas[fila]=0; reinas[fila]<nreinas; reinas[fila]++) {
  164.             if(colocarReina(fila,reinas,nreinas) == TRUE){
  165.                fila++;
  166.             }else{
  167.                break;
  168.             }
  169.          }
  170.          probados++;
  171.       }while(nposibles > probados);
  172.  
  173.       // Liberar memoria
  174.       free (reinas);
  175.   } else {
  176.       mostrarAyuda(argv[0]);
  177.   }
  178.   return 0;
  179. }
¿Podriais echarme una mano diciendome que debo cambiar y sobre todo explicarme que hago mal?
  #8 (permalink)  
Antiguo 12/05/2016, 02:46
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Saber todas las combinaciones posibles de un tablero

Lo cierto es que me parece un ejercicio un tanto raro para 8 años... es más un rompecabezas que un ejercicio jejeje
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #9 (permalink)  
Antiguo 12/05/2016, 03:54
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

pues si porque con 9 años no la veo con ecuaciones en matematicas jajaja. Es raro y creo que la idea seria que hiciera como yo, coger una cuadricula y con unas fichas hacerlo a mano para ver si se podia o no y cuales. Para esa edad no le veo utilidad matematica, es mas, supongo que seria un problema matematico de al menos 4º de la eso o bachillerato.
Tambien estoy intentando convertir el codigo de xKuZz a C pero es que no se como traducir las lineas que usa tie porque no tengo ni idea de que hace eso y lo que veo por la red habla de tuplas que no se ni que es .
  #10 (permalink)  
Antiguo 12/05/2016, 04:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Saber todas las combinaciones posibles de un tablero

std::set es un contenedor en el que los elementos están ordenados, en este caso por orden ascendente. El método insert te devuelve en un paquete (tupla) un iterador a la posición del elemento y un booleano que indica si el elemento ha sido insertado (true) o si ya existía (false). Lo que hace tie es separar esos dos valores (iterador,booleano). En este caso tie separa los elementos del paquete y los almacena en las variables que le facilitas como parámetro. El iterador no nos interesa para nada, por lo que lo almacenamos en ignore que es algo parecido a un cubo de la basura de la stl para datos que no te interesan mientras que el segundo parámetro, que indica si el valor se ha insertado en el contenedor o si ya existía lo amacena en la variable unico.

Lo que hace el algoritmo de xKuZz es insertar en el set los resultados de sumar o restar (según el caso) la fila y columna de cada ficha. Si el contenedor no tenía ese valor ya almacenado almacenará en unico un true y un false en caso contrario. Si consigues meter todos los resultados y no se repite ninguno (siempre recibes true) es que has podido ubicar las 4 fichas cumpliendo los requisitos planteados.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #11 (permalink)  
Antiguo 12/05/2016, 06:44
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 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
  #12 (permalink)  
Antiguo 12/05/2016, 10:32
Avatar de leosansan  
Fecha de Ingreso: mayo-2012
Ubicación: GRAN CANARIA
Mensajes: 194
Antigüedad: 11 años, 11 meses
Puntos: 49
Respuesta: Saber todas las combinaciones posibles de un tablero

Bueno, bueno, volviendo a que el problema se plantea para una niña de 9 añitos creo que la solución ha de ser algo más sencilla.

Para empezar a colocar los garbanzos de aguml sobre la cuadrícula de 4x4 tacharía las diagonales (es obvio pero si tienes duda inténtalo) y así colocaría el primer garbanzo en (0,1). Ahora tacharía el resto de la fila y columna así como sus diagonales (en realidad una sola más) y quedaría algo como esto:



Como se ve ya solo queda un hueco en la segunda línea, coloco el segundo garbanzo y tacho el resto de su línea, columna y diagonal (uf que pesado estoy, en realidad se tacha una sola casilla) y ya nos queda:



¡Voilá¡, ya solo quedan dos casillas donde van los garbanzos tres y cuatro.
La otra solución se puede obtener de forma similar empezando con el (0,2) o, para nosotros que no para la niña. aplicando simetría respecto a la diagonal principal.

Y aguml. entre tú, yo, en C con una cuadrícula tan pequeña pasaría de permutaciones y de todo el aparataje logístico del C++que nosotros no tenemos. Casi me quedaría con esto:

Código C++:
Ver original
  1. #include<stdio.h>
  2.  
  3. int main()  {
  4.     int i, j, a[4][4]={0};
  5.   for (i=0; i<4; i++)
  6.     for (j=0; j<4; j++){
  7.       if (i==j ||(i+j==3)){
  8.           a[i][j]=1 ;
  9.           continue;
  10.       }
  11.       if (a[i][j]==0){
  12.         a[j][i]=1;
  13.         printf ("(%2d , %2d) ---- (%2d , %2d)\n",i ,j ,j, i);
  14.         break ;
  15.       }
  16.     }
  17.   return 0 ;
  18. }

Código C++:
Ver original
  1. ( 0 ,  1) ---- ( 1 ,  0)
  2. ( 1 ,  3) ---- ( 3 ,  1)
  3. ( 2 ,  0) ---- ( 0 ,  2)
  4. ( 3 ,  2) ---- ( 2 ,  3)
  5.  
  6. Process returned 0 (0x0)   execution time : 0.006 s
  7. Press any key to continue.

Después de más de un año sin tocar un teclado estoy algo oxidado pero creo que salvo pifia mayúscula valga y os guste lo que propongo

Última edición por leosansan; 12/05/2016 a las 10:40
  #13 (permalink)  
Antiguo 12/05/2016, 11:00
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Saber todas las combinaciones posibles de un tablero

Cuánto tiempo sin saber de ti leosansan. Me alegra tenerte de vuelta
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #14 (permalink)  
Antiguo 12/05/2016, 11:26
Avatar de leosansan  
Fecha de Ingreso: mayo-2012
Ubicación: GRAN CANARIA
Mensajes: 194
Antigüedad: 11 años, 11 meses
Puntos: 49
Respuesta: Saber todas las combinaciones posibles de un tablero

Cita:
Iniciado por eferion Ver Mensaje
Cuánto tiempo sin saber de ti leosansan. Me alegra tenerte de vuelta
¡¡¡ La alegría es mutua fenómeno ¡¡¡¡
  #15 (permalink)  
Antiguo 13/05/2016, 03:42
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Pues leon sanan, creo que lo que explicas en las cuadrículas seria lo que se esperaba que hicieran pero me dijo que no explicaron nada y que cuando han resuelto en la pizarra simplemente puso los resultados sin más explicación. Con profesores así mal les ira a lo que se supone es el futuro.
Toda la demás parafernalia era por trastear e intentarlo resolver codeándo y hacerlo más flexible que un 4x4.
¿esa lógica de tachar las diagonales vale tamaños mayores o es solo para 4x4?
  #16 (permalink)  
Antiguo 13/05/2016, 03:47
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Saber todas las combinaciones posibles de un tablero

No es tachar las diagonales sino todos los espacios prohibidos... y te debería valer para cualquier tipo de tablero
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #17 (permalink)  
Antiguo 13/05/2016, 03:50
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Saber todas las combinaciones posibles de un tablero

Por cierto, si hoy trae el libro y el cuaderno les haré una foto a la parte del libro y como quedó en el cuaderno para que opinen si eso es tarea de mates o no para una niña de 9 años.

Etiquetas: combinaciones, ejercicio, int, todas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:16.