[17] Concurs - Siruri

[17] Concurs - Siruri

Postby Mihai » 11 Oct 2011, 23:08

Șiruri

Se citește din fișierul bitcell17.in un număr natural nenul N (1<=N<=1000) urmat de o matrice cu N linii și N coloane, fiecare element al matricii fiind un număr natural nenul de maximum 6 cifre.

Să se afișeze în fișierul bitcell17.out șirul de lungime maximă care poate fi format cu elemente adiacente din matricea dată (prin adiacență, se înțelege faptul că două elemente consecutive sunt vecine fie pe linie, fie pe coloană) cu condiția ca fiecare element să fie cel puțin egal cu precedentul (în afara primului element, bineînțeles).

Dacă există mai multe șiruri de lungime maximă, va fi afișat cel mai mic din punct de vedere lexicografic.

Exemplu:

bitcell17.in:


bitcell17.out:


Explicație: se pot identifica foarte multe șiruri ({1},{5},{1,5,5} șamd). Lungimea maximă a unui astfel de șir este 5, putând exemplifica două șiruri cu această lungime: {1,5,5,8,9} și {1,4,5,8,9}. Șirul mai mic din punct de vedere lexicografic este {1,4,5,8,9} așa că îl afișăm pe acesta.

Perioada de desfăşurare:

11-21 Octombrie - înscrierea în concurs
22-23 Octombrie- desemnarea câștigătorului
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [17] Concurs - Siruri

Postby Mihai » 15 Oct 2011, 15:30

Pentru că a trecut ceva timp și nu și-a arătat nimeni intenția de a participa, mă simt dator să simplific puțin problema pentru ca timpul sau dificultatea să nu mai constituie un impediment. În această direcție, considerați următoarele:

  • 1 <= N <= 100
  • dacă există mai multe șiruri de lungime maximă, se poate afișa oricare dintre ele
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [17] Concurs - Siruri

Postby nomemory » 15 Oct 2011, 18:52

Am o solutie care functioneaza pe matrici mici, nu stiu cum se descurca la numere mari . Ai niste teste pentru numere mari ?
Vreau sa optimizez putin codul inainte sa-l "inscriu in concurs" .
0,0p / 0 votes
User avatar
nomemory
Bit
 
Joined: 24 Aug 2011
Location: Bucuresti
Status: 2

Re: [17] Concurs - Siruri

Postby Mihai » 16 Oct 2011, 23:33

Din păcate, nu-ți pot da un test mare pentru că nu am avut încă timp să implementez generatorul de teste (sau soluția). Ca și indiciu, dacă ai găsit o rezolvare O(N2) poți sta liniștit.
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [17] Concurs - Siruri

Postby nomemory » 17 Oct 2011, 11:33

E departe de O(n^2), e un backtracking simplu cu niste conditii in plus . Cand ajung deseara acasa, o sa pun solutia . Pana atunci ma mai gandesc la alte solutii mai putin "brutale" .
0,0p / 0 votes
User avatar
nomemory
Bit
 
Joined: 24 Aug 2011
Location: Bucuresti
Status: 2

Re: [17] Concurs - Siruri

Postby Mihai » 22 Oct 2011, 16:42

Din păcate, nimeni nu s-a arătat interesat de acest concurs - drept urmare, nu avem un câștigător nici de această dată.
Voi reveni mâine cu o temă nouă, ceva mai ușoară, care sper că va atrage mai mulți participanți.
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [17] Concurs - Siruri

Postby new_luca » 25 Oct 2011, 22:38

Mihai , implor, hai cu o problema de nivelul meu ^:)^, probabil esti foarte ocupat asa ca iti urez spor la treaba.
0,0p / 0 votes
Image
User avatar
new_luca
Byte
 
Joined: 03 Jul 2011
Location: Gaesti
Status: 12

Re: [17] Concurs - Siruri

Postby Mihai » 25 Oct 2011, 23:43

Promit că o să o pun mâine seară (deocamdată am fost foarte ocupat cu facultatea) și îmi cer scuze pentru întârzieri.
0,0p / 0 votes
User avatar
Mihai
Byte
 
Joined: 29 Dec 2009
Status: 25

Re: [17] Concurs - Siruri

Postby nomemory » 27 Oct 2011, 09:32

Solutia mea (ineficienta, dar "straight-forward") este:

  1. #include <cstdio>
  2. #include <vector>
  3. #include <list>
  4. #include <set>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. //------------------------------------------------------------------------------
  10. // DEBUGGING MACROS
  11. //------------------------------------------------------------------------------
  12.  
  13. #define DBG
  14. #define ERROR(fmt, args...) fprintf(stderr, "ERROR: "fmt, ## args)
  15. #ifdef DBG
  16.     #define DEBUG(fmt, args...) printf(fmt, ## args)
  17. #else
  18.     #define DEBUG ;
  19. #endif
  20.  
  21. //------------------------------------------------------------------------------
  22. // CUSTOM TYPES
  23. //------------------------------------------------------------------------------
  24.  
  25. typedef struct s_Matrix {
  26.     // Uni-dimensional vector to store matrix data
  27.     vector<int> data;
  28.     // The actual matrix dimension, sqrt(matrix.size)
  29.     int size;
  30. } Matrix;
  31. #define ELEM(matrix, i, j) (matrix).data[(i) * ((matrix).size) + (j)]
  32.  
  33. typedef struct s_Position {
  34.     // Encapsulates a position in the matrix
  35.     s_Position(int i, int j) : i(i), j(j) {} ;
  36.     int i;
  37.     int j;
  38.     // We will further insert "Position" objects into a set, we'll need to
  39.     // implement the operator
  40.     friend bool operator<(s_Position const &a, s_Position const& b) {
  41.         return (a.i == b.i) ? a.j < b.j : a.i < b.i;
  42.     }
  43. } Position;
  44.  
  45. typedef struct s_Solution {
  46.     // Encapsulates the "Final solution" :)
  47.     s_Solution() : size(0), data(list<int>()) {};
  48.     int size;
  49.     list<int> data;
  50. } Solution;
  51.  
  52. //------------------------------------------------------------------------------
  53. // CONSTANTS
  54. //------------------------------------------------------------------------------
  55.  
  56. static const char * FILE_IN = "bitcell17.in";
  57. static int MAX_MATRIX_DIM = 1000;
  58. static int MAX_MATRIX_NUM = 999999;
  59. static int SUCCESS = 0;
  60. static int FAILURE = 1;
  61.  
  62. //------------------------------------------------------------------------------
  63. // FUNCTION DEFINITIONS AND DECLARATIONS
  64. //------------------------------------------------------------------------------
  65.  
  66. bool read_matrix(Matrix &matrix, const char * file_name);
  67. bool visited_contains(const set<Position> visited, const Position value);
  68. bool up_ok(const Matrix matrix, const Position source,
  69.     const set<Position> visited);
  70. bool down_ok(const Matrix matrix, const Position source,
  71.     const set<Position> visited);
  72. bool left_ok(const Matrix, const Position source,
  73.     const set<Position> visited);
  74. bool right_ok(const Matrix, const Position source,
  75.     const set<Position> visited);
  76. bool util_ok(const Matrix, const Position source, const int i_add,
  77.     const int j_add, const set<Position> visited);
  78. void get_next_positions(const Matrix matrix, const Position source,
  79.     list<Position> &next_positions);
  80. void solution(const Matrix matrix, Solution &solution);
  81.  
  82. /**
  83. * Reads a matrix from a given (input) file .
  84. * @param matrix this matrix reference will be updated with data from file
  85. * @param file_name the path to the input file .
  86. * @return true if the matrix is succesfuly updated, false otherwise
  87. */
  88. bool read_matrix(Matrix &matrix, const char * file_name)
  89. {
  90.     FILE *in = NULL;
  91.     int tmp = 0;
  92.     int lim = 0;
  93.  
  94.     in = fopen(file_name, "r");
  95.     if(!in) {
  96.         ERROR("Cannot open file %s . \n", file_name);
  97.         return (false);
  98.     }
  99.  
  100.     fscanf(in, "%d", &(matrix.size));
  101.  
  102.     if (matrix.size > MAX_MATRIX_DIM) {
  103.         // Validates matrix size
  104.         ERROR("Matrix dimension (%d) is bigger than MAX_LIMIT (%d). \n",
  105.             matrix.size, MAX_MATRIX_DIM);
  106.         fclose(in);
  107.         return (false);
  108.     }
  109.  
  110.     lim = matrix.size * matrix.size;
  111.     matrix.data.reserve(lim);
  112.     for(int i = 0; i < lim; ++i) {
  113.         fscanf(in, "%d", &tmp);
  114.         if(tmp > MAX_MATRIX_NUM) {
  115.             // Validates number limit
  116.             ERROR("\nNumber (%d) > Limit (%d)\n", tmp, MAX_MATRIX_NUM);
  117.             fclose(in);
  118.             return (false);
  119.         }
  120.         matrix.data.push_back(tmp);
  121.     }
  122.  
  123.     fclose(in);
  124.  
  125.     return (true);
  126. }
  127.  
  128. /**
  129. * Test if a given position in the matrix was already visited .
  130. * Using a set find works in O(logn) .
  131. * @param visited a set o previously visited positions .
  132. * @param position the position to test
  133. * @return a boolean value
  134. */
  135. bool visited_contains(const set<Position> visited, const Position value)
  136. {
  137.     return (visited.find(value) != visited.end());
  138. }
  139.  
  140. /**
  141. * Test if we can go to a certain position from a given source position .
  142. * @param matrix the matrix used
  143. * @param source current location in the matrix
  144. * @param i_add , 0 means we will remain on the same row, +x will shift with x
  145.             rows
  146. * @param j_add, 0 means we will remain on the same column, +y we will shift y
  147.             columns
  148. * @param a set of previously visited positions .
  149. * @see associated macros
  150. */
  151. bool util_ok(const Matrix matrix,
  152.     const Position source,
  153.     const int i_add, const int j_add,
  154.     const set<Position> visited)
  155. {
  156.     int new_i = source.i + i_add;
  157.     int new_j = source.j + j_add;
  158.     if (new_i >= 0 && new_i < matrix.size &&
  159.         new_j >= 0 && new_j < matrix.size &&
  160.         !visited_contains(visited, Position(new_i, new_j)) &&
  161.         ELEM(matrix, source.i, source.j) < ELEM(matrix, new_i, new_j)) {
  162.         return true;
  163.     }
  164.     return false;
  165. }
  166. // One row UP, keeping the same column
  167. #define OK_UP(matrix, source, visited) \
  168.     util_ok((matrix), (source), -1, 0, (visited))
  169. // One row DOWN, keeping the same column
  170. #define OK_DOWN(matrix, source, visited) \
  171.     util_ok((matrix), (source), 1, 0, (visited))
  172. // One column LEFT, keeping the same row
  173. #define OK_LEFT(matrix, source, visited) \
  174.     util_ok((matrix), (source), 0, -1, (visited))
  175. // One column RIGHT, keeping the same row
  176. #define OK_RIGHT(matrix, source, visited) \
  177.     util_ok(matrix, source, 0, 1, visited)
  178.  
  179. /**
  180. * Returns the next positions .
  181. * @param matrix
  182. * @param source the current position
  183. * @param visited previously visited positions
  184. * @param next_positions - possible postions go here
  185. */
  186. void get_next_positions(const Matrix matrix,
  187.     const Position source,
  188.     const set<Position> visited,
  189.     list<Position> &next_positions)
  190. {
  191.     if (OK_UP(matrix, source, visited)) {
  192.         next_positions.push_back(Position(source.i-1, source.j));
  193.     }
  194.     if (OK_DOWN(matrix, source, visited)) {
  195.         next_positions.push_back(Position(source.i+1, source.j));
  196.     }
  197.     if (OK_LEFT(matrix, source, visited)) {
  198.         next_positions.push_back(Position(source.i, source.j-1));
  199.     }
  200.     if (OK_RIGHT(matrix, source, visited)) {
  201.         next_positions.push_back(Position(source.i, source.j+1));
  202.     }
  203. }
  204.  
  205. /**
  206. * Backtrack from here .
  207. */
  208. void evaluate_paths(const Matrix matrix,
  209.                     const Position source,
  210.                     set<Position> &visited,
  211.                     Solution &solution,
  212.                     list<Solution> &solutions)
  213. {
  214.     list<Position> np;
  215.     // Mark the source as visited
  216.     visited.insert(source);
  217.     // Put source int the current solution
  218.     solution.data.push_back(ELEM(matrix, source.i, source.j));
  219.     solution.size += 1;
  220.     // Obtain next positions where we can go to
  221.     get_next_positions(matrix, source, visited, np);
  222.     // If this is a dead end we evaluate the solution
  223.     if (!np.size()) {
  224.         solutions.push_back(solution);
  225.     } else {
  226.         // We go to every possible path
  227.         for(list<Position>::iterator it = np.begin(); it != np.end(); ++it) {
  228.             // The visited and the solution will differ from now on, use
  229.             // the copy constructor
  230.             set<Position> new_visited(visited);
  231.             Solution new_solution(solution);
  232.             evaluate_paths(matrix, Position((*it).i, (*it).j),
  233.                            new_visited, new_solution,
  234.                            solutions);
  235.         }
  236.     }
  237. }
  238.  
  239. void solution(const Matrix matrix, Solution &max)
  240. {
  241.     list<Solution>  solutions;
  242.     // For every point in the matrix we backtrack
  243.     for(int i = 0; i < matrix.size; ++i) {
  244.         for(int j = 0; j < matrix.size ; ++j) {
  245.             set<Position> visited;
  246.             Solution tmp;
  247.             evaluate_paths(matrix, Position(i,j), visited, tmp, solutions);
  248.         }
  249.     }
  250.     // At this point solutions must be filtered
  251.     for (list<Solution>::iterator i = solutions.begin(); i != solutions.end();
  252.             i++) {
  253.         if (max.size < (*i).size) {
  254.             max = Solution(*i);
  255.         } else if (max.size == (*i).size) {
  256.             // If we more paths we the same size, choose the smallest from
  257.             // a lexicographical point of view
  258.             if(!lexicographical_compare(max.data.begin(), max.data.end(),
  259.                                      (*i).data.begin(), (*i).data.end())){
  260.                max = Solution(*i);
  261.             }
  262.         }
  263.     }
  264. }
  265.  
  266. //------------------------------------------------------------------------------
  267. // MAIN
  268. //------------------------------------------------------------------------------
  269. int main(int argc, char *argv[])
  270. {
  271.     Matrix m;
  272.     Solution max;
  273.  
  274.     // Read the matrix, into a matrix object, or fail miserably
  275.     if(!read_matrix(m, FILE_IN)) {
  276.         return (FAILURE);
  277.     }
  278.  
  279.     // Determine the longest path
  280.     solution(m, max);
  281.  
  282.     // Print solution to standard output
  283.     for(list<int>::iterator i = max.data.begin(); i !=  max.data.end(); ++i){
  284.         printf("%d ", (*i));
  285.     }
  286.  
  287.     return (SUCCESS);
  288. }


Nu am testat-o decat pe matricea primita in enunt . S-ar putea sa nu functioneze corect. Deasemenea e primul meu program in C++ (mai am insa ceva experienta cu C si Java) .
0,0p / 0 votes
User avatar
nomemory
Bit
 
Joined: 24 Aug 2011
Location: Bucuresti
Status: 2


Return to Concursuri de programare desktop

Who is online

Users browsing this forum: No registered users and 0 guests

cron