문제 링크: https://www.acmicpc.net/problem/1987
백트래킹으로 풀 수 있습니다.
백트래킹 진행할 때 방문했던 칸들의 배열을 저장할 필요 없이, 방문했던 알파벳만 저장해놓으면 됩니다. 이건 bool 배열 써도 되고, 비트마스킹 써도 되고 편한대로 구현하면 됩니다.
#pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int dy[] = { -1, 0, 1, 0 };
const int dx[] = { 0, 1, 0, -1 };
int R, C;
int board[20][20];
int max_visited;
inline bool in_range(const int& y, const int& x) {
return y >= 0 && y < R&& x >= 0 && x < C;
}
void backtrack(const int& alphabet, const int& y, const int& x, const int& cnt) {
bool moved = false;
for (int i = 0; i < 4; ++i) {
const auto& ny = y + dy[i];
const auto& nx = x + dx[i];
const auto& mask = 1 << board[ny][nx];
if (in_range(ny, nx) && !(alphabet & mask)) {
backtrack(alphabet|mask, ny, nx, cnt + 1);
moved = true;
}
}
if (!moved)
max_visited = max(max_visited, cnt);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
char x;
cin >> R >> C;
for (int i = 0; i < R; ++i)
for (int j = 0; j < C; ++j) {
cin >> x;
board[i][j] = x - 'A';
}
const auto& alphabet = 1 << board[0][0];
backtrack(alphabet, 0, 0, 1);
cout << max_visited << '\n';
return 0;
}
이게 432ms가 나왔는데 O(1) 풀이로 해도 200ms 정도는 나온다네요.
이 코드에 루프언롤링하고 범위체크하는거 빼고 등등 잡다한 최적화를 해봤더니 248ms까지는 나옵니다.
4ms 나오는 코드를 보니 getchar_unlocked를 쓰고, 함수 호출스택 대신 배열로 스택 만들어서 쓰고 뭐 그렇습니다. 저는 그렇게까지 하기는 좀.. 번거로우니 그냥 여기까지만 해야겠습니다.
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 2473: 세 용액 (0) | 2020.07.08 |
---|---|
[백준][C++] 2470: 두 용액 (0) | 2020.07.08 |
[백준][C++] 12852: 1로 만들기 2 (0) | 2020.07.08 |
[백준][C++] 2170: 선 긋기 (0) | 2020.07.08 |
[백준][C++] 3425: 고스택 (0) | 2020.07.07 |