본문 바로가기

알고리즘/🥇 골드

백준 5430 AC 파이썬 풀이, 반례

728x90

난이도 : 골드5
풀이일 : 04215
https://www.acmicpc.net/problem/5430

5430번: AC

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

www.acmicpc.net


링크로 이동하기 귀찮은 분들을 위한 문제 캡쳐


1차 시도 오답

import sys

T = int(sys.stdin.readline().strip())
for tc in range(1, T+1):
    p = list(map(str, sys.stdin.readline().strip()))
    flag = 1
    F = 0
    B = 0
    for i in range(len(p)):
        if p[i] == 'D':
            if flag:
                F += 1
            else:
                B += 1
        else:
            if flag:
                flag = 0
            else:
                flag = 1

    n = int(sys.stdin.readline().strip())
    dump = sys.stdin.readline().strip()
    result = ''
    for i in range(2*F+1, 2*n+1-2*B-1):
        result += dump[i]
    result += ''

    if len(result) > 2:
        if flag:
            print(f'[{result}]')
        else:
            print(f'[{result[::-1]}]')
    else:
        print('error')

코드 구성
1. R이 등장 할때마다 flag 를 바꿔주어 현재 정방향, 역방향 여부 기록
2. R과 입력 데이터를 참고하여 D 등장 시, 앞글자 삭제라면 F, 뒷글자 삭제라면 B + 1
3. 배열을 입력받고 배열안의 요소를 슬라이싱 결과물 출력 
4. 만약, 최종적으로 배열을 뒤집어야 한다면, 슬라이싱 결과물 뒤집어 출력
5. 출력할 수 없는 경우에는 'error' 출력
 
틀린 이유
1. 해당 코드는 주어지는 숫자가 두 자릿수 이상일 때 정답 출력 불가능


2차 시도 오답 -> 16% 틀렸습니다.

import sys

T = int(sys.stdin.readline().strip())
for tc in range(1, T+1):
    p = list(map(str, sys.stdin.readline().strip()))
    flag = 1
    F = 0
    B = 0
    for i in range(len(p)):
        if p[i] == 'D':
            if flag:
                F += 1
            else:
                B += 1
        else:
            if flag:
                flag = 0
            else:
                flag = 1

    n = int(sys.stdin.readline().strip())
    temp = sys.stdin.readline().strip()
    dump = temp[1:-1]
    dump = dump.split(',')
    result = []
    if n-B-F >= 0:
        for i in range(F, n-B):
            result.append(int(dump[i]))
        if result:
            if flag:
                print(result)
            else:
                print(result[::-1])
    else:
        print('error')

코드 변화
1. 배열을 ',' 기준으로 분리해서 받음
2. F와 B의 숫자에 맞춰 result에 출력할 요소 추가
 
틀린 이유
1. 빈리스트 일 때, []을 출력해야 하지만, 'error' 출력
2. 결과물은 띄어쓰기 없이 출력되어야함


최종 정답

# 뒤집힌 상태인지 확인하는 flag 사용
# R 참고하여 D 등장 시 F, B에 삭제 개수 저장
# 최종 배열에서 뒤집기, 앞 뒤 숫자 삭제 개수 파악 후 출력할 요소 임시 추가
# 띄어쓰기 없는 출력을 위해 문자열로 출력

# 1차 시도 틀렸습니다 -> 한 자리 숫자만 가능
# 2차 시도 16% 틀렸습니다. -> 빈 리스트면 [] 출력, 띄어쓰기 없이 출력

import sys

T = int(sys.stdin.readline().strip())
for tc in range(1, T+1):
    p = list(map(str, sys.stdin.readline().strip()))
    # 현재 요소가 D 라면 flag 따라 F, B 추가
    # flag 1이면 정방향 0이면 역방향
    flag = 1
    F = 0
    B = 0
    for i in range(len(p)):
        if p[i] == 'D':
            if flag:
                F += 1
            else:
                B += 1
        else:
            if flag:
                flag = 0
            else:
                flag = 1

    n = int(sys.stdin.readline().strip())
    temp = sys.stdin.readline().strip()
    dump = temp[1:-1]
    dump = dump.split(',')
    result = []
    if n-B-F >= 0:    # 출력할 수 있는 경우
        for i in range(F, n-B):
            result.append(int(dump[i]))
        if flag:
            sol = '['
            for j in range(len(result)):
                if j != len(result)-1:
                    sol += str(result[j]) + ','
                else:
                    sol += str(result[j])
        else:
            result = result[::-1]
            sol = '['
            for j in range(len(result)):
                if j != len(result) - 1:
                    sol += str(result[j]) + ','
                else:
                    sol += str(result[j])
        sol += ']'
        print(sol)
    else:
        print('error')

코드 변화
1. 결과물이 빈 리스트일 때도 출력 -> n-B-F >= 0 조건 추가 (이전에는 0 미포함)
2. 결과물 공백 삭제를 위해 문자열로 변환


반례

입력1
DDDD
4
[1,2,3,4]
출력[]

느낀점
처음에는 deque로 접근하려고 했는데 deque를 공부하다보니 그럴 필요가 없었다.
미리미리 자료구조를 공부해두어서 적절한 쓰임새를 잘 알아두자
시간초과를 걱정했는데 마지막 코드가 통과가 되어서 놀랐다.


04226 최적화

# 뒤집힌 상태인지 확인하는 flag 사용
# R 참고하여 D 등장 시 F, B에 삭제 개수 저장
# 최종 배열에서 뒤집기, 앞 뒤 숫자 삭제 개수 파악 후 출력할 요소 임시 추가
# 띄어쓰기 없는 출력을 위해 문자열로 출력

# 1차 시도 틀렸습니다 -> 한 자리 숫자만 가능
# 2차 시도 16% 틀렸습니다. -> 빈 리스트면 [] 출력, 띄어쓰기 없이 출력

import sys

T = int(sys.stdin.readline().strip())
for tc in range(1, T+1):
    p = list(map(str, sys.stdin.readline().strip()))
    # 현재 요소가 D 라면 flag 따라 F, B 추가
    # flag 1이면 정방향 0이면 역방향
    flag = 1
    F = 0
    B = 0
    for i in range(len(p)):
        if p[i] == 'D':
            if flag:
                F += 1
            else:
                B += 1
        else:
            if flag:
                flag = 0
            else:
                flag = 1

    n = int(sys.stdin.readline().strip())
    temp = sys.stdin.readline().strip()
    dump = temp[1:-1]
    dump = dump.split(',')
    result = []
    if n-B-F >= 0:    # 출력할 수 있는 경우
        for i in range(F, n-B):
            result.append(int(dump[i]))
        if not flag:    # flag 없다면 역방향
            result = result[::-1]
        sol = '['
        for j in range(len(result)):
            if j != len(result)-1:
                sol += str(result[j]) + ','
            else:
                sol += str(result[j])
        sol += ']'
        print(sol)
    else:
        print('error')

코드를 보다가겹치는 부분이 보여서 일부 수정
flag가 있다면 뒤집기 한 번 해주고 아래 공통 부분 코드 통합

코드 길이는 짧아졌지만 시간에는 큰 차이가 없었다.
보기에만 깔끔해진듯