inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

3-K와 문제의 단순화

3-K 질문입니다.

해결된 질문

215

yeon _leaf

작성한 질문수 22

0

http://boj.kr/41c7ab64738e4a22a04e301a8a8111ec

플러드필을 사용해서 얼음 녹이기 -> 백조 움직이기를 반복하는 로직입니다. 얼음에 큐 2개, 백조에 큐 2개를 사용했습니다.

시간 초과가 어디서 발생하는지 모르겠습니다. 제가 놓친 부분이 어디인지 궁금합니다.

C++ 코테 준비 같이 해요!

답변 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;
}

0

큰돌

아 그리고 2253001 가 base인데

문제의 범위는 1500

최대치는 3,379,501,500 인데 이거 int 범위 벗어나네요.

0

yeon _leaf

아 queue 내부에서 base i + j 식을 사용하기 때문에 최대치는 base가 아니라 base * i가 되는군요. 그 부분을 생각하지 못했습니다. 그러면 long long 자료형을 사용하거나 그냥 pair<int, int>형을 사용해야겠네요. 답변 감사합니다!!

1-E질문입니다!

0

515

2

3-L 틀린 부분 피드백 부탁드립니다.

0

816

2

1-A문제 순열재귀함수 질문입니다.

0

380

1

1-A 일곱난쟁이문제입니다

0

454

1

문제 풀 때 방향성에 대해

0

798

1

맥에서 vs code로 실행 관련 질문입니다

0

520

1

17071번 메모리 초과

0

385

1

1-C질문입니다!

0

417

2

2-B BFS 시간초과질문

0

629

2

1-O 13번 라인

0

439

1

6-J 놀이공원 문제 질문

0

380

1

구현관련 질문

0

482

1

강의 교안

0

317

1

실력을 더 올리고나서 강의를 보는 것이 맞을까요?

0

545

1

안녕하세요! 재귀함수에 관해서 질문드립니다

0

535

1

1-K

0

472

2

3-G번 질문있습니다.

1

472

3

3-C 실행 시간 질문드립니다.

0

492

1

4-A 문제 풀이 질문있습니다.

0

590

2

비트마스킹 연산자 "1의 보수" 영문 표기법

0

433

1

격자탐색 문제에서 BFS 시간복잡도 질문드립니다.

0

333

1

3-O go 함수 질문 드립니다.

1

444

2

4-A 출력 질문

0

302

1

1주차 1-O 질문드립니다

0

254

1