#include <bits/stdc++.h>
using namespace std;
int n, w, l;
int trucks[1002];
int main() {
cin >> n >> w >> l;
for (int i = 0; i < n; i++) cin >> trucks[i];
queue<int> q;
for (int i = 0; i < w; i++) q.push(0);
int now_weight = 0, min_time = 0, i = 0;
while (!q.empty()) {
now_weight -= q.front();
q.pop();
if (now_weight + trucks[i] <= l) {
if (i == n - 1) {
min_time = min_time + w + 1;
break;
}
q.push(trucks[i]);
now_weight += trucks[i];
++i;
}
else {
q.push(0);
}
++min_time;
}
cout << min_time;
}
다리를 queue로 표현하여 트럭이 없는 경우 0, 트럭이 있는 경우 트럭의 무게를 큐에 넣는다.
시간이 흐름에 따라 트럭이 다리에서 한 칸씩 이동하므로 q.pop()
으로 전진을 표현.
이후 현재 무게에 따라 새로 트럭이 올라오는지 아닌지 결정하여 0 또는 트럭의 무게를 q에 삽입.
#include <bits/stdc++.h>
using namespace std;
int maze[5][5][5], tmp_maze[5][5][5];
int dx[6] = { 1, -1, 0, 0, 0, 0 };
int dy[6] = { 0, 0, 1, -1, 0, 0, };
int dz[6] = { 0, 0, 0, 0, 1, -1 };
// 현재 좌표가 미로 내부 && 이동할 수 있는 칸인지 확인
bool check(int x, int y, int z) {
return x >= 0 && x < 5 && y >= 0 && y < 5 && z >= 0 && z < 5 && tmp_maze[z][x][y] == 1;
}
// 미로를 시계방향으로 90도 회전
void rotate(int b) {
int tmp[5][5] = {};
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
tmp[i][j] = tmp_maze[b][4 - j][i];
}
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
tmp_maze[b][i][j] = tmp[i][j];
}
}
}
void copy_board(int a, int b) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
tmp_maze[b][i][j] = maze[a][i][j];
}
}
}
// 현재 3차원 미로에서 탈출구(maze[4][4][4])까지의 최단 거리 구하기
// 자유롭게 회전 가능하므로 1024(4*4*4*4*4)가지의 모든 경우에서 계산
int solve() {
int min_dist = 100000;
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 4; b++) {
for (int c = 0; c < 4; c++) {
for (int d = 0; d < 4; d++) {
for (int e = 0; e < 4; e++) {
rotate(0);
if (tmp_maze[0][0][0] == 0) continue;
// 최단 거리 찾기(bfS)
queue<tuple<int, int, int>> q; // z, x, y
int dist[5][5][5];
fill_n(&dist[0][0][0], 125, -1);
q.push({ 0, 0, 0 });
dist[0][0][0] = 0;
while (!q.empty()) {
if (dist[4][4][4] != -1) break;
int nowz = get<0>(q.front());
int nowx = get<1>(q.front());
int nowy = get<2>(q.front());
q.pop();
for (int i = 0; i < 6; i++) {
int nextx = nowx + dx[i];
int nexty = nowy + dy[i];
int nextz = nowz + dz[i];
if (check(nextx, nexty, nextz) && dist[nextz][nextx][nexty] == -1) {
q.push({ nextz, nextx, nexty });
dist[nextz][nextx][nexty] = dist[nowz][nowx][nowy] + 1;
}
}
}
if (dist[4][4][4] == -1) continue;
min_dist = min_dist > dist[4][4][4] ? dist[4][4][4] : min_dist;
}
rotate(1);
}
rotate(2);
}
rotate(3);
}
rotate(4);
}
return min_dist;
}
// 3차원 미로의 순서 변경 (5!)
int change() {
int min_dist = 100000;
int seq[5] = { 0, 1, 2, 3, 4 };
do {
for (int i = 0; i < 5; i++) {
copy_board(seq[i], i);
}
int v = solve();
min_dist = min_dist > v ? v : min_dist;
} while (next_permutation(seq, seq + 5));
return min_dist;
}
int main() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
cin >> maze[i][j][k];
}
}
}
int dist = change();
cout << (dist == 100000 ? -1 : dist);
}
3차원 미로이기 때문에 동서남북 이동 + 상하 이동이라 dz를 추가해 이동 배열의 크기가 6이 되었다.
코드의 길이가 길지만, 그렇게 어렵지는 않은 문제인 것 같다.
모든 경우를 계산했을 때 2초의 시간 내에 통과할 수 있을 것 같아 5중 for문을 쓸 수 있었다.......
#include <bits/stdc++.h>
using namespace std;
int n, m, r, c, d;
int room[52][52];
int dx[4] = { -1, 0, 1, 0 };
int dy[4] = { 0, 1, 0, -1 };
void clean() {
int nowx = r, nowy = c, dir = d;
while (1) {
if (room[nowx][nowy] == 0) room[nowx][nowy] = 2;
bool blank = false;
for (int i = 0; i < 4; i++) {
if (room[nowx + dx[i]][nowy + dy[i]] == 0) {
blank = 1;
break;
}
}
if (blank) {
do {
dir = (dir + 3) % 4;
if(room[nowx + dx[dir]][nowy + dy[dir]] == 0) break;
} while (1);
nowx += dx[dir];
nowy += dy[dir];
continue;
}
else {
int tmp = (dir + 2) % 4;
if (room[nowx + dx[tmp]][nowy + dy[tmp]] == 1) return;
else{
nowx += dx[tmp];
nowy += dy[tmp];
continue;
}
}
}
}
int main() {
cin >> n >> m >> r >> c >> d;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> room[i][j];
}
}
clean();
int num = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (room[i][j] == 2) ++num;
}
}
cout << num;
}
문제의 조건이 조금 이해하기 힘들어서 질문 게시판에 있는 질문을 교체해 달라는 게시글을 참고했다.
room[x][y]가 0인 경우 청소 전, 1인 경우 벽, 2인 경우 청소 후로 나타냈다.
조건을 그~대로 코드로 작성하여 쉽게 해결할 수 있었다.