⚠️ 문제
https://www.acmicpc.net/problem/2503
🔐 풀이
문제에서 영수가 생각하고 있을 수 있는 정답은 1~9로 이루어진 세 자리 수이기 때문에,
우선 1~9로 이루어진 세 자리 수를 순열을 통해 모두 구해줍니다.
그리고 숫자를 한 번 물어볼 때마다 위에서 구한 숫자 리스트 중 스트라이크, 볼 개수가 맞지 않는 수를 리스트에서 제거해 나가면 마지막에 리스트에 남아있는 숫자들이 결국 영수가 생각하고 있을 수 있는 정답 숫자 리스트가 됩니다.
이 때 정답 numbers 리스트를 for문으로 순회하며 스트라이크, 볼 개수를 확인하고 삭제할 때 ❗️리스트의 길이가 변화함에 따라 순회 중 값이 누락될 수 있기 때문에 주의❗️해야 합니다.
예를 들어 리스트에 0~9까지 10개의 값이 있다고 했을 때, 인덱스 4의 5라는 값을 삭제하게 되면 길이가 9로 줄어들게 되고 인덱스 4 이후의 값들이 한 칸씩 앞으로 이동하기 때문에 결국 이전에 인덱스 5에 위치했던 값을 확인하지 않게 됩니다.
따라서 리스트를 순회하며 요소를 삭제해야할 때는 제거된 개수를 반영해 인덱스를 따로 관리하거나 삭제할 요소들을 다른 리스트에 모아두고 순회가 끝나면 한꺼번에 삭제해주어야 합니다.
🧑🏻💻 코드
import sys
from itertools import permutations
N = int(sys.stdin.readline().rstrip())
numbers = list(permutations(["1", "2", "3", "4", "5", "6", "7", "8", "9"], 3))
for _ in range(N):
question_number, strike, ball = map(int, sys.stdin.readline().split())
question_number = list(str(question_number))
# 잘못된 부분
for compare_number in numbers:
strike_cnt = 0
ball_cnt = 0
# 스트라이크, 볼 개수 확인
for j in range(3):
if question_number[j] == compare_number[j]:
strike_cnt += 1
elif question_number[j] in compare_number:
ball_cnt += 1
# 스트라이크 or 볼의 개수가 맞지 않으면 리스트에서 제거
if strike_cnt != strike or ball_cnt != ball:
numbers.remove(tuple(compare_number))
print(len(numbers))
import sys
from itertools import permutations
N = int(sys.stdin.readline().rstrip())
numbers = list(permutations(["1", "2", "3", "4", "5", "6", "7", "8", "9"], 3))
for _ in range(N):
question_number, strike, ball = map(int, sys.stdin.readline().split())
question_number = list(str(question_number))
removed = 0
# 고친 부분
for i in range(len(numbers)):
strike_cnt = 0
ball_cnt = 0
# 요소가 제거된 만큼 인덱스 조절
i -= removed
# 스트라이크, 볼 개수 확인
for j in range(3):
if question_number[j] == numbers[i][j]:
strike_cnt += 1
elif question_number[j] in numbers[i]:
ball_cnt += 1
# 스트라이크 or 볼의 개수가 맞지 않으면 리스트에서 제거
if strike_cnt != strike or ball_cnt != ball:
numbers.remove(numbers[i])
removed += 1
print(len(numbers))