problems(cpp): add “935. Knight Dialer”
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
ea77054424
commit
62436de0d0
1 changed files with 76 additions and 0 deletions
76
problems/cpp/knight-dialer.cpp
Normal file
76
problems/cpp/knight-dialer.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
using pad_t = std::array<int, 12>;
|
||||||
|
|
||||||
|
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<pad_t>& dp, int it, int idx) {
|
||||||
|
if (it < 0 || it >= static_cast<int>(dp.size())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isValidMove(idx)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[it][idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dpIteration(std::vector<pad_t>& 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<pad_t> 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);
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue