Advertisement
EmanueleBonin

Salesman in a grid

Mar 23rd, 2020
581
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.55 KB | None | 0 0
  1. #include <assert.h>
  2. #include <limits.h>
  3. #include <math.h>
  4. #include <stdbool.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9.  
  10. /*
  11. questo va in timeout
  12. 6 7
  13. 4578 5980 5767 3330 2124 218
  14. 939 251 2060 9787 8755 6121
  15. 5621 3938 3378 1305 8165 9762
  16. 67 2270 1097 4242 4043 5411
  17. 5154 4046 5506 4022 2976 1924
  18. 7383 4948 6637 74 7955 5548
  19. 4993 7425 9177 823 8305 6680 8260
  20. 2609 8482 9641 1226 355 6570 5245
  21. 9293 1555 8737 5765 8430 6262 2081
  22. 3349 7134 4314 5506 6326 9921 8248
  23. 1882 44 4541 2454 4372 2493 5490
  24. ---------------
  25. 175540
  26.  
  27.  
  28.  
  29.  
  30. 6 4
  31. 0 2 4
  32. 6 1 9
  33. 4 4 5
  34. 3 4 4
  35. 2 2 3
  36. 5 9 7
  37. 3 1 0 6
  38. 7 5 1 0
  39. 9 0 7 6
  40. 0 9 0 6
  41. 0 9 9 5
  42. -----------------
  43. 87
  44.  
  45.  
  46. */
  47.  
  48. char *Path;
  49. int PathIdx;
  50. int **Nodi; //[dim][3]; // Array con i nodi e le coordinate e il nome
  51. int path(int r, int c, int col, int **BM, int dim, int rows, int cols, int numCells, int Sum, int **Nodi, int *MinSum);
  52.  
  53.  
  54. void freeMatrix(int **M, int r){
  55.     for(int i=0;i<r;i++){
  56.         free(*(M+i));
  57.     }
  58.     free(M);
  59. }
  60.  
  61. /*
  62.  * Complete the tspGrid function below.
  63.  */
  64. int tspGrid(int horizontal_rows, int horizontal_columns, int** horizontal, int vertical_rows, int vertical_columns, int** vertical) {
  65.     int dim = horizontal_rows*vertical_columns;
  66.     int **BM; // Tabella quadrata bitmapped con tutti i nodi in x e y e le distanze sulle celle.
  67.    
  68.     int r,c;
  69.  
  70.     Path= (char *)malloc(dim*sizeof(char));
  71.     BM  = (int**)malloc(dim*sizeof(int*));
  72.     Nodi= (int**)malloc(dim*sizeof(int*));
  73.     for(int i=0; i < dim; i++){
  74.         *(Nodi+i)   = (int *)malloc(3*sizeof(int));
  75.         *(BM+i)     = (int *)malloc(dim*sizeof(int));
  76.     }
  77.  
  78.  
  79.     for(int i=0; i<dim; i++){
  80.         r = i/vertical_columns;
  81.         c = i%vertical_columns;
  82.         Nodi[i][0] = r;
  83.         Nodi[i][1] = c;
  84.         Nodi[i][2] = 'a' + i;
  85.         for(int j=0; j<dim; j++){
  86.             BM[i][j] = -1;
  87.         }
  88.     }
  89.  
  90.     int Ret=0;
  91.     //printf("r*c %d*%d\n",horizontal_rows, vertical_columns);
  92.     // se il numero di celle è pari allora prosegui pure con la ricerca
  93.     // altrimenti sarà impossibile passare su tutte le celle una sola volta
  94.     if ((dim)%2==0){
  95.         Ret = -1; // inizializzo Ret a -1 (infinito)
  96.         // metto i valori di collegamento nella matrice BM
  97.         for(int i=0; i< horizontal_rows; i++){
  98.             for(int j=0; j< horizontal_columns; j++){
  99.                 //printf("da %d,%d a %d,%d = %d in %d,%d\n", i, j, i, j+1, *(*(horizontal+i)+j), i*(horizontal_columns+1)+j, i*(horizontal_columns+1)+(j+1));
  100.                 BM[i*(horizontal_columns+1)+j][i*(horizontal_columns+1)+(j+1)] = *(*(horizontal+i)+j);
  101.                 BM[i*(horizontal_columns+1)+(j+1)][i*(horizontal_columns+1)+j] = *(*(horizontal+i)+j);
  102.             }
  103.         }
  104.  
  105.         for(int i=0; i< vertical_rows; i++){
  106.             for(int j=0; j< vertical_columns; j++){
  107.                 //printf("da %d,%d a %d,%d = %d in %d,%d\n", i, j, i+1, j, *(*(vertical+i)+j), i*vertical_columns+j, (i+1)*vertical_columns+j);
  108.                 BM[i*vertical_columns+j][(i+1)*vertical_columns+j] = *(*(vertical+i)+j);
  109.                 BM[(i+1)*vertical_columns+j][i*vertical_columns+j] = *(*(vertical+i)+j);
  110.             }
  111.         }
  112.  
  113.         /*
  114.             BM è la griglia bitmapped con le distanze tra un nodo e l'altro
  115.             la cella di partenza sarà sempre BM[0][1]
  116.             mentre la cella di arrivo deve essere BM[0][columns]
  117.             il percorso sarà chiuso se avrò effettuato rows*columns passaggi
  118.             alla lunghezza calcolata va aggiunto
  119.  
  120.         */
  121.  
  122.         PathIdx = -1;
  123.         path(0, 1, 1, BM, dim, horizontal_rows, vertical_columns, 0, 0, Nodi, &Ret);
  124.  
  125.     }
  126.     /*
  127.     for(int i=0; i<dim; i++){
  128.         printf("%d %d %c\n", Nodi[i][0], Nodi[i][1], Nodi[i][2]);
  129.     }
  130.  
  131.     for(int i=0; i<dim; i++){
  132.         for(int j=0; j<dim; j++){
  133.             printf("%d ", BM[i][j]);
  134.         }
  135.         printf("\n");
  136.     }
  137.     */
  138.     freeMatrix(BM, dim);
  139.     freeMatrix(Nodi, dim);
  140.  
  141.     return Ret;
  142. }
  143.  
  144. int Passato(char c){
  145.     int Found = 0;
  146.     for (int i=0; i<=PathIdx && Found == 0; i++){
  147.         Found = (Path[i]==c?1:0);
  148.     }
  149.     return Found;
  150. }
  151.  
  152. void StampaPath(){
  153.     for (int i=0; i<=PathIdx; i++){
  154.         printf("%c ", Path[i]);
  155.     }
  156.     printf("\n");
  157. }
  158.  
  159. int Escludi(int col, int rr, int cc, int rows, int cols){
  160.     int Ret = 0;
  161.     int indexFrom, indexTo;
  162.     if(col==1){
  163.         indexFrom   = cc;
  164.         indexTo     = rr;
  165.     } else {
  166.         indexFrom   = rr;
  167.         indexTo     = cc;
  168.     }
  169.     /*
  170.     printf("%c %c\n", Nodi[cols-2][2], Nodi[cols-1][2]);
  171.     printf("%c %c\n", Nodi[cols-1][2], Nodi[2*cols-1][2]);
  172.     printf("%c %c\n", Nodi[(rows-1)*cols-1][2], Nodi[rows*cols-1][2]);
  173.     printf("%c %c\n", Nodi[rows*cols-1][2], Nodi[rows*cols-2][2]);
  174.     printf("%c %c\n", Nodi[(rows-1)*cols+1][2], Nodi[(rows-1)*cols][2]);
  175.     printf("%c %c\n", Nodi[(rows-1)*cols][2], Nodi[(rows-2)*cols][2]);
  176.     printf("\n");
  177.     */
  178.  
  179.     if (indexFrom==indexTo)
  180.         return 1;
  181.     else if (indexFrom== 1 && indexTo==0)
  182.         return 1;
  183.     else if (indexFrom== 0 && indexTo!=1)
  184.         return 1;
  185.     else if (indexFrom==cols && indexTo!=0)
  186.         return 1;
  187.     else if (indexFrom==cols-2 && indexTo!=cols-1)
  188.         return 1;
  189.     else if (indexFrom==cols-1 && indexTo!=2*cols-1)
  190.         return 1;
  191.     else if (indexFrom==(rows-1)*cols-1 && indexTo!=rows*cols-1)
  192.         return 1;
  193.     else if (indexFrom==rows*cols-1 && indexTo!=rows*cols-2)
  194.         return 1;
  195.     else if (indexFrom==(rows-1)*cols+1 && indexTo!=(rows-1)*cols)
  196.         return 1;
  197.     else if (indexFrom==(rows-1)*cols && indexTo!=(rows-2)*cols)
  198.         return 1;
  199.  
  200.     //if (Ret == 0)
  201.         //printf("non bloccato! %c %c\n", Nodi[indexFrom][2], Nodi[indexTo][2]);
  202.      return Ret;
  203. }
  204.  
  205. int path(int r, int c, int col, int **BM, int dim, int rows, int cols, int numCells, int Sum, int **Nodi, int *MinSum){
  206.     // r,c indica quale cella di BM sto analizzando
  207.     // col indica se devo lavorare per colonna o riga
  208.     int i, j,idx, rr,cc;
  209.  
  210.     // 1) memorizza in un array tutte le
  211.     int *ch; // scelte possibili max 4
  212.     ch = (int*)malloc(4*sizeof(int));
  213.     memset(ch, 0, 4);
  214.  
  215.     idx = (col==1?c:r);
  216.     if (Passato(Nodi[idx][2])==0){
  217.         Path[++PathIdx]=Nodi[idx][2];
  218.         //printf("%d %d %c\n", r, c, Nodi[idx][2]);
  219.         for(i=0;i < dim; i++){
  220.             rr  = (col==1?i:r);
  221.             cc  = (col==1?c:i);
  222.             if(BM[rr][cc]!=-1 && Escludi(col, rr, cc, rows, cols)==0){
  223.                 Sum += BM[rr][cc];
  224.                 numCells++;
  225.                 if(rr==0 && cc==1){ // se non sono tornato all'inizio allora continua la ricerca
  226.                     // controlla se ho passato tutte le caselle
  227.                     if (numCells == rows*cols){
  228.                         //printf("percorso OK %d\n", Sum);
  229.                         //StampaPath();
  230.                         // controlla se la somma è inferiore alla somma accumulata
  231.                         if (*(MinSum) == -1 || *(MinSum) > Sum){
  232.                             *(MinSum) = Sum;
  233.                             //printf("percorso chiuso celle %d somma %d\n", numCells, Sum);
  234.                             //StampaPath();
  235.  
  236.                         }
  237.                     }
  238.                 } else {
  239.                     path(rr, cc, (col==1?0:1), BM, dim, rows, cols, numCells, Sum, Nodi, MinSum);
  240.                 }
  241.                 numCells--;
  242.                 Sum -= BM[rr][cc];
  243.             }
  244.         }
  245.         PathIdx--;
  246.     } else {
  247.         //printf("Percorso non valido %c Pathidx %d--------------\n", Nodi[idx][2], PathIdx+1);
  248.         //if (PathIdx > 22)
  249.             //StampaPath();
  250.     }
  251.     free(ch);
  252.  
  253.  
  254.     return 0;
  255. }
  256.  
  257.  
  258. int main()
  259. {
  260.     FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
  261.     int rows, columns;
  262.     int **or, **vr;
  263.  
  264.  
  265.     scanf("%d %d", &rows, &columns);
  266.     //printf("%d %d\n", rows, columns);
  267.     or=(int **)malloc(rows*sizeof(int *));
  268.     vr=(int **)malloc(columns*sizeof(int *));
  269.  
  270.     for(int i=0; i< rows; i++){
  271.         *(or+i) = (int *)malloc((columns-1)*sizeof(int));
  272.         for(int j=0; j< columns-1; j++){
  273.             //scanf("%d", (*(or+i)+j));
  274.             scanf("%d", &or[i][j]);
  275.         }
  276.     }
  277.     for(int i=0; i< rows-1; i++){
  278.         *(vr+i) = (int *)malloc(columns*sizeof(int));
  279.         for(int j=0; j< columns; j++){
  280.             scanf("%d", &vr[i][j]);
  281.         }
  282.     }
  283.  
  284.     int result = tspGrid(rows, columns-1, or, rows-1, columns, vr);
  285.  
  286.     fprintf(fptr, "%d\n", result);
  287.  
  288.     fclose(fptr);
  289.     freeMatrix(or, rows);
  290.     freeMatrix(vr, columns);
  291.     return 0;
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement