해결된 질문
작성
·
182
0
http://boj.kr/41c7ab64738e4a22a04e301a8a8111ec
플러드필을 사용해서 얼음 녹이기 -> 백조 움직이기를 반복하는 로직입니다. 얼음에 큐 2개, 백조에 큐 2개를 사용했습니다.
시간 초과가 어디서 발생하는지 모르겠습니다. 제가 놓친 부분이 어디인지 궁금합니다.
답변 1
1
한개 빼고는 잘 짜셨습니다.ㅎㅎ 백조의 호수는 좀 타이트해서 맞는 코드인데도 시간초과가 발생하기도 해요. 제가 해답코드로 제시한 코드 조차도 몇개 코드만 좀 수정하면 (맞는 로직인데도) 시간초과가 발생합니다.
그냥 이런 문제는 이런 거구나 하고 넘기시면 될 거같아요. 또한 yeon님 코드 피드백 드렸으니 참고부탁드려요.
#include <bits/stdc++.h>
using namespace std;
//good 근데 이거 범위가 1500이라서 2000을 줘도 되요.
const int base = 2253001;
int r, c;
char board[1501][1501];
int v1[1501][1501];
int v2[1501][1501];
int si, sj;
queue<int> water;
queue<int> swan;
int days;
int di[] = {-1, 0, 1, 0};
int dj[] = {0, 1, 0, -1};
void melting() {
queue<int> tmp1;
// good
while (water.size()) {
int cl = water.front(); water.pop();
int ci = cl / base;
int cj = cl % base;
for (int d=0; d<4; d++) {
int ni = ci + di[d];
int nj = cj + dj[d];
if (ni < 0 || nj < 0 || ni >= r || nj >= c || v1[ni][nj] || board[ni][nj] == 'L') continue;
if (board[ni][nj] == 'X') {
v1[ni][nj] = 1;
board[ni][nj] = '.';
tmp1.push(base * ni + nj);
continue;
}
v1[ni][nj] = 1;
water.push(base * ni + nj);
}
}
water = tmp1;
}
bool move_swan() {
queue<int> tmp2;
bool flag = 0;
while (swan.size()) {
int cl = swan.front(); swan.pop();
int ci = cl / base;
int cj = cl % base;
// good
for (int d=0; d<4; d++) {
int ni = ci + di[d];
int nj = cj + dj[d];
if (ni < 0 || nj < 0 || ni >= r || nj >= c || v2[ni][nj]) continue;
//good
if (board[ni][nj] == 'L') {
flag = 1;
break;
}
if (board[ni][nj] == 'X') {
v2[ni][nj] = 1;
tmp2.push(base * ni + nj);
continue;
}
v2[ni][nj] = 1;
swan.push(base * ni + nj);
}
if (flag) break;
}
swan = tmp2;
return flag;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> r >> c;
for (int i=0; i<r; i++) {
string line;
cin >> line;
for (int j=0; j<c; j++) {
board[i][j] = line[j];
//백조여도 물에다 푸시해줘야해요. 백조는 물위에 떠있는거니까요.
if (board[i][j] == 'L') {
si = i; sj = j;
}
if (board[i][j] == '.') {
v1[i][j] = 1;
water.push(base*i + j);
}
}
}
swan.push(base * si + sj);
v2[si][sj] = 1;
while (true) {
bool test = move_swan();
if (test) break;
melting();
days++;
}
cout << days << "\n";
return 0;
}
아 queue 내부에서 base i + j 식을 사용하기 때문에 최대치는 base가 아니라 base * i가 되는군요. 그 부분을 생각하지 못했습니다. 그러면 long long 자료형을 사용하거나 그냥 pair<int, int>형을 사용해야겠네요. 답변 감사합니다!!
아 그리고 2253001 가 base인데
문제의 범위는 1500
최대치는 3,379,501,500 인데 이거 int 범위 벗어나네요.