leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

num_paths_max_score.c (2899B)


// 1301. Number of Paths with Max Score
#include "leetcode.h"

/*
 * you are given a square 'board' of characters. you can move on the board
 * starting at the bottom right sqaure marked with the character 'S'. you need
 * to reach the top left square marked with the character 'E'. the rest of the
 * squares are labeled either with a numeric character '1, 2, ..., 9' or with an
 * obstacle 'X'. in one move you can go up, left, or up-left (diagonally) only
 * if there is no obstacle there. return a list of two integers: the first
 * integer is the maximum sum of numeric characters you can collect and the
 * second is the number of such paths that youcan take to get that maximum sum,
 * modulo 10^9 + 7.
 */

int *pathsWithMaxScore(char **board, int boardSize, int *returnSize) {
  static int mod = 1e9 + 7;
  int n = boardSize;
  int *score = (int *)malloc((n + 1) * sizeof(int));
  int *ways = (int *)calloc(n + 1, sizeof(int));
  memset(score, -1, (n + 1) * sizeof(int));
  for (int r = n - 1; r >= 0; r--) {
    int *new_score = (int *)malloc((n + 1) * sizeof(int));
    int *new_ways = (int *)calloc(n + 1, sizeof(int));
    memset(new_score, -1, (n + 1) * sizeof(int));
    for (int c = n - 1; c >= 0; c--) {
      if (board[r][c] == 'X')
        continue;
      if (board[r][c] == 'S') {
        new_score[c] = 0;
        new_ways[c] = 1;
        continue;
      }
      int best = score[c];
      best = fmax(best, new_score[c + 1]);
      best = fmax(best, score[c + 1]);
      if (best == -1)
        continue;
      long long cnt = 0;
      if (score[c] == best)
        cnt += ways[c];
      if (new_score[c + 1] == best)
        cnt += new_ways[c + 1];
      if (score[c + 1] == best)
        cnt += ways[c + 1];
      int val = board[r][c] == 'E' ? 0 : board[r][c] - '0';
      new_score[c] = best + val;
      new_ways[c] = cnt % mod;
    }
    free(score);
    free(ways);
    score = new_score;
    ways = new_ways;
  }
  int *ans = (int *)calloc(2, sizeof(int));
  *returnSize = 2;
  if (score[0] != -1) {
    ans[0] = score[0];
    ans[1] = ways[0];
  }
  free(score);
  free(ways);
  return ans;
}

int main() {
  char *b1[] = {"E23", "2X2", "12S"};
  char *b2[] = {"E12", "1X1", "21S"};
  char *b3[] = {"E11", "XXX", "11S"};
  int rs1, r1[] = {7, 1};
  int rs2, r2[] = {4, 2};
  int rs3, r3[] = {0, 0};
  int *pwms1 = pathsWithMaxScore(b1, ARRAY_SIZE(b1), &rs1);
  int *pwms2 = pathsWithMaxScore(b2, ARRAY_SIZE(b2), &rs2);
  int *pwms3 = pathsWithMaxScore(b3, ARRAY_SIZE(b3), &rs3);
  for (int i = 0; i < rs1; i++) {
    printf("%d ", pwms1[i]);
    assert(pwms1[i] == r1[i]);
  }
  printf("\n");
  for (int i = 0; i < rs2; i++) {
    printf("%d ", pwms2[i]);
    assert(pwms2[i] == r2[i]);
  }
  printf("\n");
  for (int i = 0; i < rs3; i++) {
    printf("%d ", pwms3[i]);
    assert(pwms3[i] == r3[i]);
  }
  printf("\n");
  free(pwms1);
  free(pwms2);
  free(pwms3);
}