문제
https://www.acmicpc.net/problem/17780
걸린 시간
03 : 21 : 42
풀이
C++
#include <bits/stdc++.h>
#define INF 1e9
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int n, k, y, x, d;
int dy[4] = {0, 0, -1, 1}; // E, W, N, S
int dx[4] = {1, -1, 0, 0};
vector<pair<pair<int, int>, int>> piece; // location, direction
vector<vector<pair<int, vector<int>>>> board;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> k;
board.resize(n, vector<pair<int, vector<int>>>(n));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin >> board[i][j].first;
for(int i = 0; i < k; i++){
cin >> y >> x >> d;
piece.push_back(make_pair(make_pair(y-1, x-1), d-1));
board[y-1][x-1].second.push_back(i);
}
int turn = 1;
while(turn <= 1000){
for(int i = 0; i < piece.size(); i++){
// current y, x, direction
int cy = piece[i].first.first;
int cx = piece[i].first.second;
int cd = piece[i].second;
if(board[cy][cx].second[0] != i) continue;
int ny = cy+dy[cd];
int nx = cx+dx[cd];
int nc; // next color
if(0 <= ny && ny < n && 0 <= nx && nx < n)
nc = board[ny][nx].first;
else
nc = 2;
switch(nc){
case 0: // white
if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
cout << turn;
return 0;
}
for(int i = 0; i < board[cy][cx].second.size(); i++){
piece[board[cy][cx].second[i]].first.first = ny;
piece[board[cy][cx].second[i]].first.second = nx;
}
board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
board[cy][cx].second.clear();
break;
case 1: // red
if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
cout << turn;
return 0;
}
for(int i = 0; i < board[cy][cx].second.size(); i++){
piece[board[cy][cx].second[i]].first.first = ny;
piece[board[cy][cx].second[i]].first.second = nx;
}
reverse(board[cy][cx].second.begin(), board[cy][cx].second.end());
board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
board[cy][cx].second.clear();
break;
case 2: // blue
int rd; // reverse direction
switch(cd){
case 0:
rd = 1;
break;
case 1:
rd = 0;
break;
case 2:
rd = 3;
break;
case 3:
rd = 2;
break;
}
piece[i].second = rd;
ny = cy+dy[rd];
nx = cx+dx[rd];
if(0 <= ny && ny < n && 0 <= nx && nx < n){
switch(board[ny][nx].first){
case 0:
if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
cout << turn;
return 0;
}
for(int i = 0; i < board[cy][cx].second.size(); i++){
piece[board[cy][cx].second[i]].first.first = ny;
piece[board[cy][cx].second[i]].first.second = nx;
}
board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
board[cy][cx].second.clear();
break;
case 1:
if(board[ny][nx].second.size() + board[cy][cx].second.size() >= 4){
cout << turn;
return 0;
}
for(int i = 0; i < board[cy][cx].second.size(); i++){
piece[board[cy][cx].second[i]].first.first = ny;
piece[board[cy][cx].second[i]].first.second = nx;
}
reverse(board[cy][cx].second.begin(), board[cy][cx].second.end());
board[ny][nx].second.insert(board[ny][nx].second.end(), board[cy][cx].second.begin(), board[cy][cx].second.end());
board[cy][cx].second.clear();
break;
case 2:
// do nothing
break;
}
}
break;
}
}
turn++;
}
cout << -1;
return 0;
}
- '상' 방향값 잘못 설정.
- 모든 말의 개수만큼 반복하지 않음.
- "가장 아래에 있는 말만 이동할 수 있다." 말만 -> 말로만 으로 이해.
- 말들이 같이 이동할 때 쌓여져 있는 다른 말들의 좌표를 수정해주지 않음.
문제 이해부터 구현까지 모두 꼼꼼하지 못해서 디버깅에 아주 많은 시간이 걸렸다. 구현, 시뮬레이션 문제에서는 되도록이면 구조체나 클래스를 따로 작성해서 구현하는 편이 좋을 것 같다.
'Baekjoon' 카테고리의 다른 글
Baekjoon 1800번 인터넷 설치 (0) | 2020.10.21 |
---|---|
Baekjoon 16918번 봄버맨 (0) | 2020.10.19 |
Baekjoon 15591번 MooTube (Silver) (0) | 2020.10.19 |
Baekjoon 10021번 Watering the Fields (0) | 2020.10.15 |
Baekjoon 11967번 불켜기 (0) | 2020.10.14 |
댓글