[BOJ] 3190번 : 뱀
2024. 8. 23. 09:10ㆍAlgorithm
1. problem :
https://www.acmicpc.net/problem/3190
2. solution 1 :
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int n, k, l; // board 크기, 사과 개수, 방향 변환 횟수;
int board[102][102];
int isvis[102][102];
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
pair<int, int> head = { 0,0 };
deque<pair<int, int>> snake;
queue<pair<int, char>> dir_loc; // 방향변환 <시간,방향> 저장
bool isover = false; // game 끝났는지
int gametime;
int curdir = 1;
void go(int dir) {
head.X += dx[dir];
head.Y += dy[dir];
if (head.X < 0 || head.X >= n || head.Y < 0 || head.Y >= n || isvis[head.X][head.Y] == 1) {
isover = true;
return;
}
isvis[head.X][head.Y] = 1;
snake.push_front({ head.X,head.Y });
if (board[head.X][head.Y] == 1) {
board[head.X][head.Y] = 0;
}
else {
isvis[snake.back().X][snake.back().Y] = 0;
snake.pop_back();
}
}
void change_dir(int todir) {
if (todir == 'D') curdir = (1 + curdir) % 4;
else curdir = (3 + curdir) % 4;
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
cin >> k;
while (k--) {
int x, y;
cin >> x >> y;
board[x - 1][y - 1] = 1;
}
cin >> l;
for (int i = 0; i < l; i++) {
int t;
char v;
cin >> t >> v;
dir_loc.push({ t,v });
}
snake.push_back({ 0,0 });
isvis[0][0] = 1;
while (1) {
gametime++;
go(curdir);
if (isover) break;
if (!dir_loc.empty() && dir_loc.front().X == gametime) {
change_dir(dir_loc.front().Y);
dir_loc.pop();
}
}
cout << gametime << '\n';
}
deque을 이용해서 뱀이 있는 좌표를 추적하는 것을 놓쳤다.
3. solution 2 :
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int n, k, l; // 보드 크기, 사과 개수, 방향 변환 횟수
int board[102][102];
int isvis[102][102];
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
queue<pair<int, char>> dir_loc; // 방향변환 <시간,방향> 저장
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
cin >> k;
for (int i = 0; i < k; i++) {
int x, y;
cin >> x >> y;
board[x-1][y-1] = 1; // 사과 위치 설정
}
cin >> l;
for (int i = 0; i < l; i++) {
int t;
char v;
cin >> t >> v;
dir_loc.push({t, v});
}
deque<pair<int, int>> snake; // 뱀의 위치를 저장할 덱
snake.push_back({0, 0});
isvis[0][0] = 1;
int gametime = 0;
int curdir = 1;
while (true) {
gametime++;
int nx = snake.front().X + dx[curdir];
int ny = snake.front().Y + dy[curdir];
// 벽에 부딪히거나 자기자신의 몸에 부딪히면 게임 종료
if (nx < 0 || nx >= n || ny < 0 || ny >= n || isvis[nx][ny]) {
break;
}
// 뱀이 이동
snake.push_front({nx, ny});
isvis[nx][ny] = 1;
if (board[nx][ny] == 1) { // 사과가 있다면
board[nx][ny] = 0; // 사과를 먹음
} else { // 사과가 없다면 꼬리를 줄임
isvis[snake.back().X][snake.back().Y] = 0;
snake.pop_back();
}
// 방향 전환
if (!dir_loc.empty() && dir_loc.front().X == gametime) {
char dir = dir_loc.front().Y;
dir_loc.pop();
if (dir == 'D') {
curdir = (curdir + 1) % 4; // 오른쪽 회전
} else {
curdir = (curdir + 3) % 4; // 왼쪽 회전
}
}
}
cout << gametime << '\n';
}
훨씬 깔끔한 풀이. chatgpt가 작성했다. deque의 front를 사실상 head의 좌표로 이용해서 전진할 때, 이용하고 있다. 이게 훨씬 낫네.
4. solution 3 :
// Authored by : yongjunleeme
// Co-authored by : -
// http://boj.kr/7a74fe31a87c42ffbaa39e94711ae557
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int n, k;
int a, b, c, l;
char d;
int board[105][105]; // 1: 뱀, 2: 사과
int second = 0;
int dx[4] = {1, 0, -1, 0}; // [1][0]: 아래, [0][1]: 오른쪽, [-1][0]: 위, [0][-1]: 왼쪽
int dy[4] = {0, 1, 0, -1};
deque<pair<int, int>> dq;
queue<pair<int, char>> switchDir;
int main(void){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
cin >> k;
while(k--){
cin >> a >> b;
// 사과
board[a][b] = 2;
}
cin >> l;
while(l--){
// 방향전환
cin >> c >> d;
switchDir.push({c, d});
}
dq.push_front({1,1});
int dir = 1;
while(1){
dir %= 4;
auto cur = dq.front();
board[cur.X][cur.Y] = 1;
second++;
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if(nx < 1 || nx > n || ny < 1 || ny > n) break;
if(board[nx][ny] == 1) break;
if(board[nx][ny] != 2) {
auto tail = dq.back();
board[tail.X][tail.Y] = 0;
dq.pop_back();
}
auto sd = switchDir.front();
if(sd.X == second){
if(sd.Y == 'L') dir += 1;
else if(sd.Y == 'D') dir += 3;
switchDir.pop();
}
dq.push_front({nx, ny});
}
cout << second;
}
source code 출처 : https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x0D/solutions/3190.cpp
basic-algo-lecture/0x0D/solutions/3190.cpp at master · encrypted-def/basic-algo-lecture
바킹독의 실전 알고리즘 강의 자료. Contribute to encrypted-def/basic-algo-lecture development by creating an account on GitHub.
github.com
'Algorithm' 카테고리의 다른 글
| [BOJ] 13460번 : 구슬 탈출 2 (0) | 2024.08.24 |
|---|---|
| [BOJ] 14500번 : 테트로미노 (0) | 2024.08.23 |
| [BOJ] 14503번 : 로봇 청소기 (0) | 2024.08.22 |
| [BOJ] 16985번 : Maaaaaaaaaze (0) | 2024.08.22 |
| [BOJ] 13335번 : 트럭 (0) | 2024.08.22 |