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

zhu님의 프로필 이미지

작성한 질문수

세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)

BOJ 2580

시간초과를 자력으로 해결하지 못했습니다 😓

해결된 질문

24.08.15 16:20 작성

·

98

0

안녕하세요, 강의를 듣고 계신 여러분!

여러분의 학습을 돕기 위해 질문 안내를 드리고자 합니다.

 

1. chatGPT를 이용해보기

  • 단순한 의문은 chatGPT를 이용해도 해답을 찾을 수 있는 경우가 종종 있습니다!

     

 

2. 강의의 어떤 부분에 대한 질문이고, 어떤 부분이 궁금한지 명확히 알려주세요!

  • 강의의 어느 파트에서 의문을 느끼고, 어떤 부분이 궁금한지를 명확히 제시해 주시면 답변에 도움이 됩니다!

  • 자신은 어떻게 이해했는지 또한 적어주면 좋습니다!

 

ex) 섹션5의 '그래프 순회 (DFS & BFS) [개념]' 강의에서 DFS와 BFS 모두 그래프의 모든 노드를 탐색하는 알고리즘이라고 하셨고 시간 복잡도 또한 똑같다고 이해했습니다. 그러면 DFS와 BFS 중에서 어떤 알고리즘이 더 효율적인지 구별하는 것은 의미가 없는 것일까요?

 

  • 어느 파트

    • 섹션5의 '그래프 순회 (DFS & BFS) [개념]' 강의

  • 자신은 어떻게 이해했는지

    • DFS와 BFS 모두 그래프의 모든 노드를 탐색하는 알고리즘이라고 하셨고 시간 복잡도 또한 똑같다고 이해

  • 어떤 부분이 궁금한지

     

    • DFS와 BFS 중에서 어떤 알고리즘이 더 효율적인지 구별하는 것은 의미가 없는 것일까요?

안녕하세요. 선생님.

저번 설명과 조언 너무 감사합니다.

 

그,, 백준 2580 스도쿠에 관한 질문인데요,

시간 초과를 해결하지 못하였는데,

각각을 보면 그렇게까지 시간이 많이 들지는 않을 거 같다는 생각도 들구..

재귀를 사용하지는 않았지만,

어디서 시간이 많이 걸리는 지 분석이 안되어서요..

선생님 도움이 필요해서 질문 남깁니다..

 

arr = [list(map(int, input().split())) for _ in range(9)] # 스도구 문제 배열
idxs = [] # 인덱스 쌍을 담는 배열
for i in range(9):
	for j in range(9):
		if not arr[i][j]: idxs.append((i,j))
def fillHori(y, x): # 가로
	nums = 45 # 1~9까지의 합
	for i in range(9):
		if x == i: continue # 자기 자신 탐색 제외
		if arr[y][i] == 0: return 0 # 0이 또 있으면 채울 수 없음
		nums -= arr[y][i]	
	return nums
def fillVerti(y, x): #세로
	nums = 45 # 1~9까지의 합
	for i in range(9):
		if y == i: continue # 자기 자신 탐색 제외
		if arr[i][x] == 0: return 0 # 0이 또 있으면 채울 수 없음
		nums -= arr[i][x]
	return nums
def fillSquare(y, x): #사각형
	nums = 45 # 1~9까지의 합
	for i in range(y // 3 * 3, y // 3 * 3 + 3):
		for j in range(x // 3 * 3, x // 3 * 3 + 3):
			if y == i and x == j: continue # 자기 자신 탐색 제외
			if arr[i][j] == 0: return 0 # 0이 또 있으면 채울 수 없음
			nums -= arr[i][j]	 
	return nums
def fillCrossDown(y, x): # 대각선(안씀)
	nums = 45 # 1~9까지의 합
	for i in range(9):
		for j in range(9):
			if y == i and x == j: continue # 자기 자신 탐색 제외
			if arr[i][j] == 0: return 0 # 0이 또 있으면 채울 수 없음
			if y - x == j - i: nums -= arr[i][j]
	return nums
def fillCrossUp(y, x): # 대각선(안씀)
	nums = 45 # 1~9까지의 합
	for i in range(9):
		for j in range(9):
			if y == i and x == j: continue # 자기 자신 탐색 제외
			if arr[i][j] == 0: return 0 # 0이 또 있으면 채울 수 없음
			if y + x == j + i: nums -= arr[i][j]
	return nums
while idxs:
	for i, j in idxs:
		n = fillHori(i, j)
		if n: 
			arr[i][j] = n; idxs.remove((i,j)); continue
		n = fillVerti(i, j)
		if n: 
			arr[i][j] = n; idxs.remove((i,j)); continue
		n = fillSquare(i, j)
		if n: 
			arr[i][j] = n; idxs.remove((i,j)); continue
		n = fillCrossUp(i, j)
		if n: 
			arr[i][j] = n; idxs.remove((i,j)); continue
		n = fillCrossDown(i, j)
		if n: 
			arr[i][j] = n; idxs.remove((i,j))
for a in arr:
	for i in a: print(i, end = ' ')
	print()

답변 2

1

알리 Ally님의 프로필 이미지
알리 Ally
지식공유자

2024. 08. 17. 14:16

안녕하세요. zhu님!

 

작성해주신 코드를 보니, 입력 보드에서 0으로 비어있는 곳의 좌표를 idxs에 담아 각 케이스 메소드들을 돌며 숫자를 채우고 idxs 좌표를 하나씩 지워가는 걸로 보입니다.

 

현재 시간초과가 나는 이유는 하나의 숫자로 확정이 안 되는 경우가 존재해서 무한루프가 도는 걸로 추측됩니다.

현재 순회하고 있는 fillHori, fillVerti, fillSquare, fillCrossUp, fillCrossDown 5가지의 메소드들을 모두 순회하여도 (i ,j) 좌표에 값이 채워지지 않는 경우 계속 (i,j) 좌표를 while문으로 탐색하게 되면서 무한루프가 발생합니다.

 

다음 테스트 케이스를 통해 위 케이스를 테스트 해보실 수 있습니다.

1 3 5 4 6 9 2 7 8
7 0 0 1 3 5 6 4 9
4 6 9 2 7 8 1 3 5
3 0 0 5 4 6 8 9 7
8 7 4 9 1 3 5 2 6
5 9 6 8 2 7 4 1 3
9 1 7 6 5 2 3 8 4
6 4 3 7 8 1 9 5 2
2 5 8 3 9 4 7 6 1

 

또 궁금하신 점 있으시면 언제든 질문 부탁드립니다.

감사합니다. :)

zhu님의 프로필 이미지
zhu
질문자

2024. 08. 19. 05:13

헉.. 문제에 있는 스도쿠는 스도쿠를 풀기 위한(?) 문제라기보다는,,

뭐랄까.. 스도쿠 판이 될 수 있는 예시를 완성하는(?) 문제였군요!!

(소싯적 스도쿠 할 때 1~9 중에서도 후보군 좁힌 거 중에서 걸렀던 거 같기도 하지만.. ㅠ)

 

알려주신 부분이 분명 맞을 거 같아요!

감사합니다!

 

+

아, 문제 설명 출력 쪽에

스도쿠 판을 채우는 방법이 여럿인 경우는 그 중 하나만을 출력한다.

라고 되어있는데.. ㅠ

문제 꼼꼼하게 읽으면서 요목조목 따져보고 풀어야겠어요 ㅠ

0

인프런 AI 인턴님의 프로필 이미지

2024. 08. 15. 16:26

안녕하세요, 인프런 AI 인턴입니다.

zhu님의 질문은 백준 2580 스도쿠 문제에 관한 시간 초과 문제 해결에 대한 질문으로 보입니다. 파이썬으로 스도쿠 문제를 해결하면서 발생한 시간 초과 문제를 어떻게 해결할 수 있을지 고민 중이신 것 같네요.

비슷한 유형의 질문으로, 시간복잡도 해결에 관한 조언을 제공한 기존 답변이 있습니다. 이 답변에서는 일반적으로 시간 초과를 해결하는 데 도움이 될 수 있는 팁들을 제공하고 있습니다. 질문 내용과 직접적으로 일치하지는 않지만, 시간 복잡도 문제를 해결하는 데 일반적인 가이드라인을 제공할 수 있습니다.

“저.. 시간복잡도 관련 질문입니다.(로직 거의 비슷한 거 같은데, 시간초과가 나서요)” - 이 질문에서는 시간 초과 문제 해결에 관한 설명과 함께, 입력 방법 최적화, 불필요한 반복 제거, 백트래킹 기법의 효율적 사용 등 여러 팁을 제공하고 있습니다. 특히 sys.stdin.readline 사용 시 주의사항에 대해서도 언급되어 있는데, 이는 입력을 받는 방식이 문제 해결에 영향을 줄 수 있음을 나타냅니다.

Python으로 구현할 때, 시간 초과를 해결하기 위해 고려해야 할 사항들은 다양합니다. 예를 들어, 가능한 모든 경우의 수를 직접 탐색하는 대신, 상태 공간 트리를 사용하여 가능성이 없는 경우를 빨리 거르고 (Pruning), 필요한 경우만 탐색(Backtracking)하도록 할 수 있습니다. 또한, 반복문 내에서의 연산 최적화, 재귀 대신 반복문 사용, 불필요한 계산 제거 등 다양한 방법으로 시간 복잡도를 개선할 수 있습니다.

스도쿠 문제 해결 시, 효율적인 검증 로직과 가능한 경우의 수를 줄이는 방법에 초점을 맞춰보세요. 예를 들어, 행, 열, 그리고 3x3 구역 내에서 가능한 숫자를 빠르게 체크하고, 가능한 숫자의 조합만을 대상으로 재귀적 호출을 진행하는 것이 좋습니다.

질문에 제시된 코드만으로는 구체적인 이유를 파악하기 어렵고, 강의 내용과 직접적으로 연결된 예시가 아니기 때문에 더 상세한 조언이 필요할 경우, 스도쿠 문제에 대한 구체적인 시간 복잡도 최적화 방안을 검색하거나, 관련 커뮤니티에 질문을 올려 다양한 해결책을 모색하는 것을 추천드립니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

zhu님의 프로필 이미지

작성한 질문수

질문하기