인프런 커뮤니티 질문&답변

권창덕님의 프로필 이미지
권창덕

작성한 질문수

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

3-J

3-J 시간 초과 원인을 파악하기 어렵습니다.

작성

·

275

·

수정됨

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

http://boj.kr/edd8ff505fdf4958ad6c322bae97ec8d

 

혹시 로직에 문제가 있어 시간 초과가 생기는 것인지, pair를 사용해서 시간 초과가 생기는 것인지 궁금합니다.

 

만약 pair를 사용해서 시간 초과가 생기는 것이라면, 제 생각에는 pair가 큰 영향을 주지 않을 것으로 생각되는데 혹시 어떤 이유에서 pair가 실행 시간에 영향을 줄 수 있는지 궁금합니다.

 

또, 만약 그렇다면 코딩 테스트에서 pair를 사용하지 말아야 할 경우를 어떤 근거로 판단할 수 있을지 궁금합니다.

답변 1

0

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 창덕님 ㅎㅎ

제 생각에는 문제를 잘못 파악하신 거 같습니다.

문제를 볼까요?

둘째 줄에 주난이의 위치 x1, y1과 범인의 위치 x2, y2가 주어진다. (1 ≤ x1, x2 ≤ N, 1 ≤ y1, y2 ≤ M)

이후 N×M 크기의 교실 정보가 주어진다. 0은 빈 공간, 1은 친구, *는 주난, #는 범인을 뜻한다.

	q.push(startPos);
	visited[startPos.first][startPos.second] = 1;

	for (int i = 0; i < 2; i++)
	{
		char dummy;
		cin >> dummy;
	}

위치에 관한 로직이 잘못된 것 같습니다.

만약 pair를 사용해서 시간 초과가 생기는 것이라면, 제 생각에는 pair가 큰 영향을 주지 않을 것으로 생각되는데 혹시 어떤 이유에서 pair가 실행 시간에 영향을 줄 수 있는지 궁금합니다.

>> pair는 큰 영향을 주지 않습니다.

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.


권창덕님의 프로필 이미지
권창덕
질문자

주난이의 위치를 startPos에 입력받아 큐에 push한 후 방문 정보를 기록하고 범인의 위치는 어차피 BFS를 수행하는 과정에서 '#'을 만나면 범인의 위치이므로 필요 없다고 생각해서 버리기 위해 for문을 돌렸습니다.

 

문제의 예시를 봤을때, 주난이의 위치가 y성분 x성분 순으로 들어오고 인덱스가 1부터 시작하지만 저는 0부터 사용하므로 1씩 뺀 후 startPos에 할당했습니다.

 

혹시 제가 이해한 내용 중 잘못된 내용이 있을까요?

큰돌님의 프로필 이미지
큰돌
지식공유자

아 이해했습니다.

코드 상의 문제도 없어보이고 반례 몇개를 생각해서 집어넣어봤는데 잘 안되네요..

해당 부분 반례 찾는대로 다시 답변 드리겠습니다.

 

감사합니다.

큰돌님의 프로필 이미지
큰돌
지식공유자

반례 찾았습니다.

틀린 부분은 더미에 있었습니다.

더미는 char형입니다. 즉, 한 문자밖에 받지 못합니다. 하지만 이 문제의 범위는 300이기 때문에 3글자까지도 입력으로 올 수 있게 됩니다.

 

이렇게 한번 고쳐보시겠어요?

#include <iostream>
#include <queue>

using namespace std;

char map[304][304];
int visited[304][304];

int dy[4] = { 0, 0, 1, -1 };
int dx[4] = { 1, -1, 0, 0 };

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int N, M;
	cin >> N >> M;

	queue<pair<int, int>> q;
	queue<pair<int, int>> readyQ;

	pair<int, int> startPos;
	int temp;
	cin >> temp;
	startPos.first = temp - 1;
	cin >> temp;
	startPos.second = temp - 1;
	
	q.push(startPos);
	visited[startPos.first][startPos.second] = 1;

	for (int i = 0; i < 2; i++)
	{
    int aa;  
		cin >> aa;
	}
	
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cin >> map[i][j];
		}
	}

	int ans = 0;

	while (true)
	{
		ans++;

		while (!readyQ.empty())
		{
			q.push(readyQ.front());
			readyQ.pop();
		}

		while (!q.empty())
		{
			int y = q.front().first;
			int x = q.front().second;
			q.pop();

			for (int i = 0; i < 4; i++)
			{
				int newY = y + dy[i];
				int newX = x + dx[i];

				if (newY < 0 || newY >= N || newX < 0 || newX >= M)
					continue;
				if (visited[newY][newX])
					continue;

				if (map[newY][newX] == '0')
				{
					q.push({ newY, newX });
					visited[newY][newX] = 1;
				}
				else if (map[newY][newX] == '1')
				{
					readyQ.push({ newY, newX });
					visited[newY][newX] = 1;
				}
				else if (map[newY][newX] == '#')
				{
					cout << ans;
					return 0;
				}
			}
		}
	}

	return 0;
}
권창덕님의 프로필 이미지
권창덕
질문자

이해했습니다! 감사합니다!

권창덕님의 프로필 이미지
권창덕

작성한 질문수

질문하기