Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #define max(x, y) (((x) > (y)) ? (x) : (y))
- #define min(x, y) (((x) < (y)) ? (x) : (y))
- #define rows M
- #define cols N
- // Returns length of the longest path beginning with mat[i][j].
- // This function mainly uses lookup table dp[n][n]
- int M, N;
- int d_max = -1;
- int findLongestDropping(int y, int x, int mat[rows][cols], int dpd[rows][cols], int v_vex[rows][cols], int prev_y, int prev_x)
- {
- if (y < 0 || y >= cols || x < 0 || x >= cols)
- return 0;
- if (dpd[y][x] != -1)
- return dpd[y][x];
- if (v_vex[y][x] != -1)
- return M*N;
- // To store the path lengths in all the four directions
- int h, g, w, z = w = g = h = M*N;
- // Since all numbers are unique and in range from 1 to n*n,
- // there is atmost one possible direction from any cell
- if (x < cols - 1 && x + 1 != prev_x && (mat[y][x] >= mat[y][x + 1]))
- h = findLongestDropping(y, x + 1, mat, dpd, v_vex, y, x);
- if (x > 0 && x - 1 != prev_x && (mat[y][x] >= mat[y][x - 1]))
- g = findLongestDropping(y, x - 1, mat, dpd, v_vex, y, x);
- if (y > 0 && y - 1 != prev_y && (mat[y][x] >= mat[y - 1][x]))
- z = findLongestDropping(y - 1, x, mat, dpd, v_vex, y, x);
- if (y < rows - 1 && y + 1 != prev_y && (mat[y][x] >= mat[y + 1][x]))
- w = findLongestDropping(y + 1, x, mat, dpd, v_vex, y, x);
- // If none of the adjacent fours is one greater we will take 1
- // otherwise we will pick maximum from all the four directions
- return dpd[y][x] = min(h - 1, min(g - 1, min(z - 1, min(w - 1, M*N))));
- }
- int findLongestRising(int y, int x, int mat[rows][cols], int dpr[rows][cols], int dpd[rows][cols], int v_vex[rows][cols], int prev_y, int prev_x, int depth)
- {
- if (y < 0 || y >= rows || x < 0 || x >= cols)
- return 0;
- v_vex[y][x] = 1;
- // If this subproblem is already solved
- if (dpr[y][x] != -1){
- return dpr[y][x];
- }
- // To store the path lengths in all the four directions
- int h = -1, g = -1, z = -1, w = -1;
- // Since all numbers are unique and in range from 1 to n*n,
- // there is atmost one possible direction from any cell
- if (x < cols - 1 && x + 1 != prev_x && (mat[y][x] <= mat[y][x + 1]))
- h = 1 + findLongestRising(y, x + 1, mat, dpr, dpd, v_vex, y, x, depth + 1);
- if (x > 0 && x - 1 != prev_x && (mat[y][x] <= mat[y][x - 1]))
- g = 1 + findLongestRising(y, x - 1, mat, dpr, dpd, v_vex, y, x, depth + 1);
- if (y > 0 && y - 1 != prev_y && (mat[y][x] <= mat[y - 1][x]))
- z = 1 + findLongestRising(y - 1, x, mat, dpr, dpd, v_vex, y, x, depth + 1);
- if (y < rows - 1 && y + 1 != prev_y && (mat[y][x] <= mat[y + 1][x]))
- w = 1 + findLongestRising(y + 1, x, mat, dpr, dpd, v_vex, y, x, depth + 1);
- v_vex[y][x] = -1;
- int dpdt[rows][cols];
- memset(dpdt, -1, sizeof dpdt);
- //dpd[y][x] = M*N - max(0, findLongestDropping(y, x, mat, dpdt, v_vex, -1, -1)) + dpr[x][y] + 1;
- d_max = max(d_max, M*N - max(0, findLongestDropping(y, x, mat, dpdt, v_vex, -1, -1)) - 1 + depth);
- // If none of the adjacent fours is one greater we will take 1
- // otherwise we will pick maximum from all the four direction
- return dpr[y][x] = max(h, max(g, max(z, max(w, 1))));//result_dropping))));
- }
- // Returns length of the longest path beginning with any cell
- int finLongestOverAll(int mat[rows][cols])
- {
- int result = 1; // Initialize result
- // Create a lookup table and fill all entries in it as -1
- int dpr[rows][cols];
- int dpd[rows][cols];
- int v_vex[rows][cols];
- memset(dpr, -1, sizeof dpr);
- memset(dpd, -1, sizeof dpd);
- memset(v_vex, -1, sizeof v_vex);
- // Compute longest path beginning from all cells
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- if (dpr[i][j] == -1) {
- findLongestRising(i, j, mat, dpr, dpd, v_vex, -1, -1, 1);
- memset(dpr, -1, sizeof dpr);
- }
- // Update result if needed
- result = max(result, dpr[i][j]);
- }
- }
- return d_max;
- }
- int gen_nums(int S){
- return 75 * S % 65537;
- }
- // Driver program
- int main()
- {
- int rep;
- scanf("%d", &rep);
- for(int r = 0; r < rep; r++){
- d_max = -1;
- int S;
- scanf("%d %d %d", &S, &M, &N);
- int matrix[M][N];
- /*M = 5;
- N = 5;
- int matrix[5][5] = {{1, 2, 3, 4, 5},
- {2, 0, 4, 4, 6},
- {2, 0, 9, 8, 7},
- {2, 12, 10, 5, 7},
- {3, 4, 7, 4, 3}};*/
- for(int y = 0; y < M; y++) {
- printf("\n");
- for (int x = 0; x < N; x++) {
- matrix[y][x] = S = gen_nums(S);
- printf("%d ", S);
- }
- }
- printf("%d\n", finLongestOverAll(matrix));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment