#include #include #include #include class Solution { using pad_t = std::array; static bool isValidMove(int i) { return i >= 0 && i < 12 && i != 9 && i != 11; } static int index(int x, int y) { if (x < 0 || x >= 3 || y < 0 || y >= 4) { return -1; } return y * 3 + x; } static int add(int x, int y) { return (x + y) % 1000000007; } static int get(const std::vector &dp, int it, int idx) { if (it < 0 || it >= static_cast(dp.size())) { return 0; } if (!isValidMove(idx)) { return 0; } return dp[it][idx]; } static void dpIteration(std::vector &dp, int it) { for (int i = 0; i < 12; ++i) { if (!isValidMove(i)) { continue; } int dx = -2, dy = -1; for (int j = 0; j < 8; ++j) { auto next = index(i % 3 + dx, i / 3 + dy); dp[it][i] = add(dp[it][i], get(dp, it - 1, next)); // adjustment of the dx, dy dy *= -1; if (j % 2 == 1) { dx *= -1; } if (j % 4 == 3) { int d = dx; dx = dy; dy = d; } } } } public: int knightDialer(int n) { std::vector dp(n); dp[0].fill(1); dp[0][9] = 0; dp[0][11] = 0; for (int i = 1; i < n; ++i) { dpIteration(dp, i); } return std::accumulate(dp.back().begin(), dp.back().end(), 0, add); } };