[백준] 17070 파이프 옮기기 1
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
vector<vector<int>> board;
int cache[17][17][3];
vector<vector<pair<int, int>>> cond0 = { {{0, 2}} , {{0, 2}, {1, 1}, {1, 2}} };
vector<vector<pair<int, int>>> cond1 = { {{2, 0}} , {{1, 1}, {2, 0}, {2, 1}} };
vector<vector<pair<int, int>>> cond2 = { {{1, 2}} , {{2, 1}}, {{1, 2}, {2, 1}, {2, 2}} };
bool inRange(int r, int c) {
if ((r < 0) || (r >= N)) return false;
if ((c < 0) || (c >= N)) return false;
return true;
}
int solve(int r, int c, int state) {
if (state == 0) {
if ((r == (N - 1)) && (c == (N - 2))) return 1;
}
else if (state == 1) {
if ((r == (N - 2)) && (c == (N - 1))) return 1;
}
else if (state == 2) {
if ((r == (N - 2)) && (c == (N - 2))) return 1;
}
int& ret = cache[r][c][state];
if (ret != -1) return ret;
ret = 0;
if (state == 0) {
bool possible = true;
for (int i = 0; i < cond0[0].size(); ++i) {
int nextR = r + cond0[0][i].first;
int nextC = c + cond0[0][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r, c + 1, 0);
possible = true;
for (int i = 0; i < cond0[1].size(); ++i) {
int nextR = r + cond0[1][i].first;
int nextC = c + cond0[1][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r, c + 1, 2);
}
else if (state == 1) {
bool possible = true;
for (int i = 0; i < cond1[0].size(); ++i) {
int nextR = r + cond1[0][i].first;
int nextC = c + cond1[0][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r+1, c, 1);
possible = true;
for (int i = 0; i < cond1[1].size(); ++i) {
int nextR = r + cond1[1][i].first;
int nextC = c + cond1[1][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r + 1, c, 2);
}
else if (state == 2) {
bool possible = true;
for (int i = 0; i < cond2[0].size(); ++i) {
int nextR = r + cond2[0][i].first;
int nextC = c + cond2[0][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r+1, c + 1, 0);
possible = true;
for (int i = 0; i < cond2[1].size(); ++i) {
int nextR = r + cond2[1][i].first;
int nextC = c + cond2[1][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r+1, c + 1, 1);
possible = true;
for (int i = 0; i < cond2[2].size(); ++i) {
int nextR = r + cond2[2][i].first;
int nextC = c + cond2[2][i].second;
if (!inRange(nextR, nextC) || (board[nextR][nextC] == 1)) {
possible = false;
break;
}
}
if (possible) ret += solve(r+1, c + 1, 2);
}
return ret;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N;
for (int i = 0; i < N; ++i) {
vector<int> inputV;
for (int j = 0; j < N; ++j) {
int input;
cin >> input;
inputV.push_back(input);
}
board.push_back(inputV);
}
for (int i = 0; i < 17; ++i) {
for (int j = 0; j < 17; ++j) {
cache[i][j][0] = -1;
cache[i][j][1] = -1;
cache[i][j][2] = -1;
}
}
cout << solve(0, 0, 0);
return 0;
}