[SWEA][S/W 문제해결 기본] D3 문제풀이

EunBi Na·2022년 11월 16일
0

1206. [S/W 문제해결 기본] 1일차 - View

링크텍스트
강변에 빌딩들이 옆으로 빽빽하게 밀집한 지역이 있다. 이곳에서는 빌딩들이 너무 좌우로 밀집하여, 강에 대한 조망은 모든 세대에서 좋지만 왼쪽 또는 오른쪽 창문을 열었을 때 바로 앞에 옆 건물이 보이는 경우가 허다하였다.

그래서 이 지역에서는 왼쪽과 오른쪽으로 창문을 열었을 때, 양쪽 모두 거리 2 이상의 공간이 확보될 때 조망권이 확보된다고 말한다. 빌딩들에 대한 정보가 주어질 때, 조망권이 확보된 세대의 수를 반환하는 프로그램을 작성하시오.

아래와 같이 강변에 8채의 빌딩이 있을 때, 연두색으로 색칠된 여섯 세대에서는 좌우로 2칸 이상의 공백이 존재하므로 조망권이 확보된다. 따라서 답은 6이 된다.

A와 B로 표시된 세대의 경우는 왼쪽 조망은 2칸 이상 확보가 되었지만 오른쪽 조망은 한 칸 밖에 확보가 되지 않으므로 조망권을 확보하지 못하였다. C의 경우는 반대로 오른쪽 조망은 2칸이 확보가 되었지만 왼쪽 조망이 한 칸 밖에 확보되지 않았다.

[제약 사항]
가로 길이는 항상 1000이하로 주어진다.
맨 왼쪽 두 칸과 맨 오른쪽 두 칸에는 건물이 지어지지 않는다. (예시에서 빨간색 땅 부분)
각 빌딩의 높이는 최대 255이다.

[입력]
총 10개의 테스트케이스가 주어진다.
각 테스트케이스의 첫 번째 줄에는 건물의 개수 N이 주어진다. (4 ≤ N ≤ 1000)
그 다음 줄에는 N개의 건물의 높이가 주어진다. (0 ≤ 각 건물의 높이 ≤ 255)
맨 왼쪽 두 칸과 맨 오른쪽 두 칸에 있는 건물은 항상 높이가 0이다. (예시에서 빨간색 땅 부분)

[출력]
#부호와 함께 테스트케이스의 번호를 출력하고, 공백 문자 후 조망권이 확보된 세대의 수를 출력한다.

T = 10 # 대문자 상수
for tc in range(1, T+1):
    N = int(input())
    arr = list(map(int, input().split()))
    ans = 0

    # 2 ~ N-2 각각 검사해서
    for i in range(2, N-2):
        min_value = 987654321
        # 기준 건물과 왼쪽 오른쪽 2개 차의 최소값
        for j in range(5):
            if j != 2:
                if arr[i] - arr[i-2+j] < min_value:
                    min_value = arr[i] - arr[i-2+j]
        # 최소값이 양수이면 조망권이 확보
        if min_value > 0 :
            ans += min_value
    print("#{} {}".format(tc, ans))
for t in range(1, 11) :
    N = int(input())
    building = list(map(int, input().split()))

    view = 0
    for i in range(2, N-2) :
        def_2 = building[i] - building[i-2]
        def_1 = building[i] - building[i-1]
        def1 = building[i] - building[i+1]
        def2 = building[i] - building[i+2]
        if def_2 > 0 and def_1 > 0 and def1 > 0 and def2 > 0 :
            view += min(def_2, def_1, def1, def2)

    print("#{} {}".format(t, view))

1208. [S/W 문제해결 기본] 1일차 - Flatten

링크텍스트
한 쪽 벽면에 다음과 같이 노란색 상자들이 쌓여 있다.
높은 곳의 상자를 낮은 곳에 옮기는 방식으로 최고점과 최저점의 간격을 줄이는 작업을 평탄화라고 한다.
평탄화를 모두 수행하고 나면, 가장 높은 곳과 가장 낮은 곳의 차이가 최대 1 이내가 된다.
평탄화 작업을 위해서 상자를 옮기는 작업 횟수에 제한이 걸려있을 때, 제한된 횟수만큼 옮기는 작업을 한 후 최고점과 최저점의 차이를 반환하는 프로그램을 작성하시오.

가장 높은 곳에 있는 상자를 가장 낮은 곳으로 옮기는 작업을 덤프라고 정의한다.
위의 예시에서 제1회 덤프를 수행한 이후 화면은 다음과 같다.
A부분의 상자를 가장 낮은 B부분에 덤프하였으며, A대신 A’부분의 상자를 사용해도 무방하다.
다음은 제2회 덤프를 수행한 이후의 화면이다.
A’부분의 상자를 옮겨서, C부분에 덤프하였다. 이때 C 대신 C’부분에 덤프해도 무방하다.
2회의 덤프 후, 최고점과 최저점의 차이는 8 – 2 = 6 이 되었다 (최초덤프 이전에는 9 – 1 = 8 이었다). 덤프 횟수가 2회로 제한된다면, 이 예시 문제의 정답은 6이 된다.

[제약 사항]
가로 길이는 항상 100으로 주어진다.
모든 위치에서 상자의 높이는 1이상 100이하로 주어진다.
덤프 횟수는 1이상 1000이하로 주어진다.
주어진 덤프 횟수 이내에 평탄화가 완료되면 더 이상 덤프를 수행할 수 없으므로 그 때의 최고점과 최저점의 높이 차를 반환한다 (주어진 data에 따라 0 또는 1이 된다).

[입력]
총 10개의 테스트 케이스가 주어지며, 각 테스트 케이스의 첫 번째 줄에는 덤프 횟수가 주어진다. 그리고 다음 줄에 각 상자의 높이값이 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스의 최고점과 최저점의 높이 차를 출력한다.

N = 10 #TC 개수
for i in range(1, N + 1):
    M = int(input()) # 상자 이동 가능 횟수
    arr = list(map(int, input().split())) # 상자 배열
    for j in range(M): # 상자 이동 가능 횟수 동안
        maxVal = max(arr) # 최댓값
        minVal = min(arr) # 최솟값
        minIdx = arr.index(minVal) # 최솟값 idx
        maxIdx = arr.index(maxVal) # 최댓값 idx
        arr[minIdx] += 1 # 최댓값 idx의 값에서 1 빼기
        arr[maxIdx] -= 1 # 최소값 idx의 값에서 1 더하기
    answer = max(arr) - min(arr) # 최댓값 - 최소값을 출력 결과로 
    print("#", i, " ", answer, sep='')

1209. [S/W 문제해결 기본] 2일차 - Sum

다음 100X100의 2차원 배열이 주어질 때, 각 행의 합, 각 열의 합, 각 대각선의 합 중 최댓값을 구하는 프로그램을 작성하여라. 다음과 같은 5X5 배열에서 최댓값은 29이다.

[제약 사항]
총 10개의 테스트 케이스가 주어진다.
배열의 크기는 100X100으로 동일하다.
각 행의 합은 integer 범위를 넘어가지 않는다.
동일한 최댓값이 있을 경우, 하나의 값만 출력한다.

[입력]
각 테스트 케이스의 첫 줄에는 테스트 케이스 번호가 주어지고 그 다음 줄부터는 2차원 배열의 각 행 값이 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스의 답을 출력한다.

for _ in range(1, 11):
    test_case = int(input())
    array = [list(map(int, input().split())) for _ in range(100)]
    answer = 0

    for i in range(100):
        temp = 0
        for j in range(100):
            temp += array[i][j]
        answer = max(answer, temp)

    for i in range(100):
        temp = 0
        for j in range(100):
            temp += array[j][i]
        answer = max(answer, temp)

    temp = 0
    for i in range(100):
        temp += array[i][i]
    answer = max(answer, temp)

    print(f"#{test_case} {answer}")

1213. [S/W 문제해결 기본] 3일차 - String

주어지는 영어 문장에서 특정한 문자열의 개수를 반환하는 프로그램을 작성하여라.

Starteatingwellwiththeseeighttipsforhealthyeating,whichcoverthebasicsofahealthydietandgoodnutrition.

위 문장에서 ti 를 검색하면, 답은 4이다.

[제약 사항]
총 10개의 테스트 케이스가 주어진다.
문장의 길이는 1000자를 넘어가지 않는다.
한 문장에서 검색하는 문자열의 길이는 최대 10을 넘지 않는다.
한 문장에서는 하나의 문자열만 검색한다.

[입력]
각 테스트 케이스의 첫 줄에는 테스트 케이스의 번호가 주어지고 그 다음 줄에는 찾을 문자열, 그 다음 줄에는 검색할 문장이 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스의 답을 출력한다.

for _ in range(1, 11):
    test_case = int(input())
    target = input() #ti
    sentence = input() #주어지는 영어 문장
    print(f"#{test_case} {sentence.count(target)}")

1215. [S/W 문제해결 기본] 3일차 - 회문1

"기러기", "토마토", "스위스"와 같이 똑바로 읽어도 거꾸로 읽어도 똑같은 문장이나 낱말을 회문(回文, palindrome)이라 한다. 8x8 평면 글자판에서 제시된 길이를 가진 회문의 개수를 구하라.

위와 같은 글자판이 주어졌을 때, 길이가 5인 회문은 붉은색 테두리로 표시된 4개이므로 4를 반환하면 된다.

[제약 사항]
각 칸의 들어가는 글자는 'A', 'B', 'C' 중 하나이다. ABA도 회문이며, ABBA도 회문이다. A 또한 길이 1짜리 회문이다. 가로 또는 세로로 이어진 회문의 개수만 센다. 아래 그림에서 노란색 경로를 따라가면 길이 7짜리 회문이 되지만 직선이 아니기 때문에 인정되지 않는다.

[입력]
총 10개의 테스트 케이스가 주어진다.각 테스트 케이스의 첫 번째 줄에는 찾아야 하는 회문의 길이가 주어지며, 다음 줄에 8x8 크기의 글자판이 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 찾은 회문의 개수를 출력한다.

def find_palindrome(array):
    result = 0

    for line in array:
        for i in range(8 - n + 1): #8x8 글자판
            target = line[i:i+n]
            if target == target[::-1]:
                result += 1

    return result


for test_case in range(1, 11):
    n = int(input())
    board = [list(input().strip()) for _ in range(8)]

    answer = find_palindrome(board)
    board = list(zip(*board[::-1]))
    answer += find_palindrome(board)
    
    print(f"#{test_case} {answer}")

< zip 함수 활용 >

전치행렬 생성

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = list(zip(*a))
b
>>> [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

a 리스트의 각 요소인 리스트 들을 zip으로 묶어줄 수 있습니다.
이를 통해서 transform 한 것과 같은 효과를 확인할 수 있습니다.

1216. [S/W 문제해결 기본] 3일차 - 회문2

"기러기" 또는 "level" 과 같이 거꾸로 읽어도 제대로 읽은 것과 같은 문장이나 낱말을 회문(回文, palindrome)이라 한다.
주어진 100x100 평면 글자판에서 가로, 세로를 모두 보아 가장 긴 회문의 길이를 구하는 문제이다.

위와 같은 글자 판이 주어졌을 때, 길이가 가장 긴 회문은 붉은색 테두리로 표시된 7칸짜리 회문이다. 예시의 경우 설명을 위해 글자판의 크기가 100 x 100이 아닌 8 x 8으로 주어졌음에 주의한다.

[제약사항]
각 칸의 들어가는 글자는 c언어 char type으로 주어지며 'A', 'B', 'C' 중 하나이다. 글자 판은 무조건 정사각형으로 주어진다.
ABA도 회문이며, ABBA도 회문
이다. A또한 길이 1짜리 회문이다.
가로, 세로 각각에 대해서 직선으로만 판단한다. 즉, 아래 예에서 노란색 경로를 따라가면 길이 7짜리 회문이 되지만 직선이 아니기 때문에 인정되지 않는다.

[입력]
각 테스트 케이스의 첫 번째 줄에는 테스트 케이스의 번호가 주어지며, 바로 다음 줄에 테스트 케이스가 주어진다.
총 10개의 테스트케이스가 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 찾은 회문의 길이를 출력한다.

# import sys
# sys.stdin=open("input3.txt")
#회문 검사 함수
def check(lst):
    for i in range(len(lst)//2):
        if lst[i]!=lst[-i-1]:
            return False
    return True
#각 행에 대해서 검사할 것이기 때문에 가로기준 arr과 세로기준 arr2를 생성
for tc in range(1,11):
    T = int(input())
    arr = [list(input()) for _ in range(100)]
    #arr2는 arr의 전치행렬이다.
    arr2 = list(zip(*arr))
    max_v = 1 #길이가 1인 문자열 자체가 회문이므로 1로 초기화

#최대길이부터 거꾸로 검사한다
#해당 길이에서 최대값을 저장하게 되면 같은 길이나 그보다 작은 길이에서는 
#검사할 필요가 없으므로 break선언


    for length in range(100,1,-1):
        if max_v >= length:
            break
        for idx in range(100-length+1):
            if max_v == length:
                break
            for lst, lst2 in zip(arr, arr2):
                if check(lst[idx:idx+length]) or check(lst2[idx:idx+length]):
                    max_v = length
                    break
    print('#{} {}'.format(tc,max_v))

1217. [S/W 문제해결 기본] 4일차 - 거듭 제곱

다음과 같이 두 개의 숫자 N, M이 주어질 때, N의 M 거듭제곱 값을 구하는 프로그램을 재귀호출을 이용하여 구현해 보아라.
2 5 = 2 X 2 X 2 X 2 X 2 = 32
3 6 = 3 X 3 X 3 X 3 X 3 X 3 = 729

[제약 사항]
총 10개의 테스트 케이스가 주어진다.
결과 값은 Integer 범위를 넘어가지 않는다.

[입력]
각 테스트 케이스의 첫 줄에는 테스트 케이스의 번호가 주어지고 그 다음 줄에는 두 개의 숫자가 주어진다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스에 대한 답을 출력한다.

for _ in range(10) :
    T = int(input())
    N, M = map(int, input().split())

    def power(N, M) :
        if M == 0 :
            return 1
        else:
            return N * power(N, M-1)

    print("#{} {}".format(T, power(N, M)))

1220. [S/W 문제해결 기본] 5일차 - Magnetic

테이블 위에 자성체들이 놓여 있다. 자성체들은 성질에 따라 색이 부여되는데, 푸른 자성체의 경우 N극에 이끌리는 성질을 가지고 있고, 붉은 자성체의 경우 S극에 이끌리는 성질이 있다.
아래와 같은 테이블에서 일정 간격을 두고 강한 자기장을 걸었을 때, 시간이 흐른 뒤에 자성체들이 서로 충돌하여 테이블 위에 남아있는 교착 상태의 개수를 구하라.
아래는 자성체들이 놓여 있는 테이블을 위에서 바라본 모습이다.

A로 표시된 붉은 자성체의 경우 S극에 이끌리면서 테이블 아래로 떨어지게 된다.
B로 표시된 푸른 자성체의 경우 N극에 이끌리면서 테이블 아래로 떨어지게 된다.
나머지 자성체들은 서로 충돌하며, 교착 상태에 빠져 움직이지 않게 된다.
D로 표시된 자성체들에서 알 수 있듯 한 쪽 방향으로 움직이는 자성체의 개수가 많더라도 반대 방향으로 움직이는 자성체가 하나라도 있으면 교착 상태에 빠져 움직이지 않는다.
D로 표시된 자성체들과 같이 셋 이상의 자성체들이 서로 충돌하여 붙어 있을 경우에도 하나의 교착 상태로 본다.
C와 D는 좌우로 인접하여 있으나 각각 다른 교착 상태로 판단하여 2개의 교착 상태로 본다.
E의 경우와 같이 한 줄에 두 개 이상의 교착 상태가 발생할 수도 있다.
F의 경우 각각 다른 교착상태로 판단하여 2개의 교착상태로 본다.
위의 예시의 경우 테이블 위에 남아있는 교착상태는 7개이므로 7를 반환한다.

[제약 사항]
자성체는 테이블 앞뒤 쪽에 있는 N극 또는 S극에만 반응하며 자성체끼리는 전혀 반응하지 않는다.
테이블의 크기는 100x100으로 주어진다. (예시에서는 설명을 위해 7x7로 주어졌음에 유의)

[입력]
10개의 테스트 케이스가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 정사각형 테이블의 한 변의 길이가 주어진다. (이 값은 항상 100이다)

그 다음 줄부터 100 x 100크기의 테이블의 초기 모습이 주어진다. 1은 N극 성질을 가지는 자성체를 2는 S극 성질을 가지는 자성체를 의미하며 테이블의 윗부분에 N극이 아래부분에 S극이 위치한다고 가정한다.
(N극 성질을 가지는 자성체는 S극에 이끌리는 성질이 있다.)

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 교착 상태의 개수를 출력한다.

T = 10
for tc in range(1, T+1):
    N = int(input())
    a = [list(map(int, input().split())) for _ in range(N)]
    # 1: N극 성질-> 빨강이  2: S극 성질-> 파랭이

    cnt = 0
    for j in range(N):  # (0,j) 열탐색
        r, c = 0, j
        stack = []
        # 아래로 내려가면서 <1--2> 의 순서이면 체킹
        while r < N:
            if not stack and a[r][c] == 1:  # 스택이 비어있는 상태이면서 1 이면 stack에 넣음
                stack.append(1)
            elif stack and a[r][c] == 2:  # 스택에 1이 있는 상태에서 2가 나오면 pop 해서 cnt에 더해주기
                cnt += stack.pop()
            r += 1  # 아래로 진행하기 위해 row 인덱스 증가시켜주기

    print("#{} {}".format(tc, cnt))

1221. [S/W 문제해결 기본] 5일차 - GNS

숫자 체계가 우리와 다른 어느 행성이 있다. 아래는 이 행성에서 사용하는 0 ~ 9의 값을 순서대로 나타낸 것이다.
"ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"
0 ~ 9 의 값을 나타내는 단어가 섞여 있는 문자열을 받아 작은 수부터 차례로 정렬하여 출력하는 프로그램을 작성하라.
예를 들어 입력 문자열이 "TWO NIN TWO TWO FIV FOR" 일 경우 정렬한 문자열은 "TWO TWO TWO FOR FIV NIN" 이 된다.

[입력]
입력 파일의 첫 번째 줄에는 테스트 케이스의 개수가 주어진다.
그 다음 줄에 #기호와 함께 테스트 케이스의 번호가 주어지고 공백문자 후 테스트 케이스의 길이가 주어진다.
그 다음 줄부터 바로 테스트 케이스가 주어진다. 단어와 단어 사이는 하나의 공백으로 구분하며, 문자열의 길이 N은 100≤N≤10000이다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 정렬된 문자열을 출력한다.

T = int(input())
# 정렬용 알파벳
number_alpha = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]
 
for tc in range(1,1+T):
    n = list(map(str,input().split()))
    # 무작위 숫자 리스트
    number_list = list(map(str,input().split()))
    # 결과 저장용
    res = []
 
    for q in range(10):
        for w in number_list:
            if number_alpha[q] == w:
                res.append(w)
    print(n[0])
    print(*res)
T = int(input())
num = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]

for tc in range(1, T+1):
    n = list(map(str, input().split()))
    number_list = list(map(str, input().split()))
    res = []

    for i in range(10):
        for j in number_list:
            if num[i] == j:
                res.append(j)
    print(n[0])
    print(*res)

1225. [S/W 문제해결 기본] 7일차 - 암호생성기

다음 주어진 조건에 따라 n개의 수를 처리하면 8자리의 암호를 생성할 수 있다.

  • 8개의 숫자를 입력 받는다.
  • 첫 번째 숫자를 1 감소한 뒤, 맨 뒤로 보낸다.
    다음 첫 번째 수는 2 감소한 뒤 맨 뒤로, 그 다음 첫 번째 수는 3을 감소하고 맨 뒤로, 그 다음 수는 4, 그 다음 수는 5를 감소한다.
    이와 같은 작업을 한 사이클이라 한다.
  • 숫자가 감소할 때 0보다 작아지는 경우 0으로 유지되며, 프로그램은 종료된다. 이 때의 8자리의 숫자 값이 암호가 된다.

[제약 사항]
주어지는 각 수는 integer 범위를 넘지 않는다.
마지막 암호 배열은 모두 한 자리 수로 구성되어 있다.

[입력]
각 테스트 케이스의 첫 줄에는 테스트 케이스의 번호가 주어지고, 그 다음 줄에는 8개의 데이터가 주어진다.

[출력]
#부호와 함께 테스트케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스의 답을 출력한다.

T = 10
for t in range(1, T+1):
    tc = int(input())
    queue = list(map(int, input().split()))

    i = 1
    while True:
        if i > 5:
            i = 1
        t = queue.pop(0) - i
        if t <= 0:
            queue.append(0)
            break
        queue.append(t)
        i += 1

    print("#{} {} {} {} {} {} {} {} {}".format(tc, *queue))
import collections

T = 10
for t in range(1, T+1):
    tc = int(input())
    queue2 = collections.deque(list(map(int, input().split())), maxlen=8)

    i = 1
    while True:
        if i > 5:
            i = 1
        t = queue2.popleft() - i
        if t <= 0:
            queue2.append(0)
            break
        queue2.append(t)
        i += 1

    print("#{}".format(tc), end=" ")
    for q in queue2:
        print("{}".format(q), end=" ")
    print()
    # 출력형태는 여러가지로 할 수 있다.
    # print("#{}".format(tc), end=" ")
    # print(*queue2, end=" ")
    # print()

1~5가 한사이클이었다.
꺼내서 숫자를 깍는데 제일 앞의 숫자를 꺼낸다.
숫자를 감소시키고 나서 제일 뒤에 넣어준다.
0보다 작다면 0으로 바꿔주고 암호생성을 멈춘다.

#D3 1225 암호생성기
T = 10
for t in range(1, T+1):
    input()
    password = list(map(int, input().split()))
    i = 1
    while True:
        a = password.pop(0) - i
        #0보다 작아지면 0으로 바꿔준다.
        if a < 0: a = 0
        password.append(a)
        #마지막 숫자가 0이 되었다면 그암호가 되므로 반복문 종료
        if a <= 0: break
        i += 1
        #한사이클은 5까지이므로 숫자 갱신
        if i > 5: i = 1
    print('#{} '.format(t), end='')
    print(*password)

1228. [S/W 문제해결 기본] 8일차 - 암호문1

0 ~ 999999 사이의 수를 나열하여 만든 암호문이 있다.
암호문을 급히 수정해야 할 일이 발생했는데, 이 암호문은 특수 제작된 처리기로만 수정이 가능하다.
이 처리기는 다음과 같이 1개의 기능을 제공한다.

  1. I(삽입) x, y, s : 앞에서부터 x의 위치 바로 다음에 y개의 숫자를 삽입한다. s는 덧붙일 숫자들이다. [ ex) I 3 2 123152 487651 ]

위의 규칙에 맞게 작성된 명령어를 나열하여 만든 문자열이 주어졌을 때, 암호문을 수정하고, 수정된 결과의 처음 10개 숫자를 출력하는 프로그램을 작성하여라.

[입력]
첫 번째 줄 : 원본 암호문의 길이 N ( 10 ≤ N ≤ 20 의 정수)
두 번째 줄 : 원본 암호문
세 번째 줄 : 명령어의 개수 ( 5 ≤ N ≤ 10 의 정수)
네 번째 줄 : 명령어
위와 같은 네 줄이 한 개의 테스트 케이스이며, 총 10개의 테스트 케이스가 주어진다.

[출력]
#기호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 수정된 암호문의 처음 10개 항을 출력한다.

for tc in range(1, 11) :
    n = int(input())
    data = list(map(int, input().split()))
    o = int(input())
    order = list(input().split())

    type = ''
    pos = -1
    cnt = -1
    for i in range(len(order)) :
        if order[i] == 'I' :
            type = order[i]
            pos = -1
            cnt = -1
        else :
            if type == 'I' :
                if pos == -1 :
                    pos = int(order[i])
                    continue
                else :
                    if cnt == -1 :
                        cnt = int(order[i])
                        continue

                    data.insert(pos, order[i])
                    pos += 1

    print('#%d' % tc, end=' ')
    print(*data[:10])
  1. 각 테스트 케이스마다 원본 암호문(data)과 명령어(order)를 리스트 형태로 구성한다.

  2. order 리스트의 요소를 순서대로 하나씩 확인하며, 만약 해당 값이 'I' 일 경우 type을 해당 문자로 갱신하고, pos와 cnt를 -1로 설정한다.

  3. 해당 값이 숫자라면 아래와 같은 작업을 수행한다.

  • 만약 type이 'I'이고 pos가 -1이라면, 현재 값이 삽입할 위치를 의미하므로 pos에 해당 값(정수형으로 변환)을 할당하고 continue한다.
  • 만약 type이 'I'이고 pos가 -1이 아니고 cnt가 -1이라면, 현재 값이 삽입할 값의 개수를 의미하므로 cnt에 해당 값(정수형으로 변환)을 할당하고 continue한다.
  • cnt가 -1인지 확인하는 부분까지 continue가 되지 않았다면, 현재의 값이 삽입할 값을 의미하므로 data리스트의 pos 위치에 해당 값을 삽입한 후 pos 값을 1 증가시킨다.
  1. 최종적으로 해당 테스트 케이스 번호와 함께 암호문의 처음 10개 항을 출력한다.
for t in range(1, 11) :
    N = int(input())
    code = list(map(int, input().split()))
    M = int(input())
    instruction = list(input().split())

    ins = []
    for i in range(len(instruction)) :
        if instruction[i] == "I" :
            if i != 0 :
                ins.append(tmp)
            tmp = []
        elif i == len(instruction)-1 :
            tmp.append(int(instruction[i]))
            ins.append(tmp)
        else :
            tmp.append(int(instruction[i]))

    for i in range(M) :
        x = ins[i][0]
        y = ins[i][1]
        s = ins[i][2:]
        for j in range(y) :
            code.insert(x+j, s[j])

    print("#{} {} {} {} {} {} {} {} {} {} {}".format(t, *code))

1229. [S/W 문제해결 기본] 8일차 - 암호문2

0 ~ 999999 사이의 수를 나열하여 만든 암호문이 있다. 암호문을 급히 수정해야 할 일이 발생했는데,

이 암호문은 특수 제작된 처리기로만 수정이 가능하다. 이 처리기는 다음과 같이 2개의 기능을 제공한다.

1.I(삽입) x, y, s : 앞에서부터 x의 위치 바로 다음에 y개의 숫자를 삽입한다. s는 덧붙일 숫자들이다.[ ex) I 3 2 123152 487651 ]

  1. D(삭제) x, y : 앞에서부터 x의 위치 바로 다음부터 y개의 숫자를 삭제한다.[ ex) D 4 4 ]

위의 규칙에 맞게 작성된 명령어를 나열하여 만든 문자열이 주어졌을 때, 암호문을 수정하고, 수정된 결과의 처음 10개 숫자를 출력하는 프로그램을 작성하여라.

[입력]
첫 번째 줄 : 원본 암호문의 길이 N ( 100 ≤ N ≤ 200 의 정수)
두 번째 줄 : 원본 암호문
세 번째 줄 : 명령어의 개수 ( 10 ≤ N ≤ 20 의 정수)
네 번째 줄 : 명령어
위와 같은 네 줄이 한 개의 테스트 케이스이며, 총 10개의 테스트 케이스가 주어진다.

[출력]
#기호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 수정된 암호문의 처음 10개 항을 출력한다.

for t in range(1, 11) :
    N = int(input())
    code = list(map(int, input().split()))
    M = int(input())
    instruction = list(input().split())

    ins = []
    for i in range(len(instruction)) :
        if instruction[i] == "I" or instruction[i] == "D" :
            if i != 0 :
                ins.append(tmp)
            tmp = [instruction[i]]
        elif i == len(instruction)-1 :
            tmp.append(instruction[i])
            ins.append(tmp)
        else :
            tmp.append(instruction[i])

    for i in range(M) :
        if ins[i][0] == "I" :
            x = int(ins[i][1])
            y = int(ins[i][2])
            s = ins[i][3:]
            for j in range(y) :
                code.insert(x+j, int(s[j]))
        elif ins[i][0] == "D" :
            x = int(ins[i][1])
            y = int(ins[i][2])
            for j in range(y) :
                del(code[x])

    print("#{} {} {} {} {} {} {} {} {} {} {}".format(t, *code))

1230. [S/W 문제해결 기본] 8일차 - 암호문3

0 ~ 999999 사이의 수를 나열하여 만든 암호문이 있다.
암호문을 급히 수정해야 할 일이 발생했는데, 이 암호문은 특수 제작된 처리기로만 수정이 가능하다.
이 처리기는 다음과 같이 3개의 기능을 제공한다.

  1. I(삽입) x, y, s : 앞에서부터 x의 위치 바로 다음에 y개의 숫자를 삽입한다. s는 덧붙일 숫자들이다.[ ex) I 3 2 123152 487651 ]

  2. D(삭제) x, y : 앞에서부터 x의 위치 바로 다음부터 y개의 숫자를 삭제한다.[ ex) D 4 4 ]

  3. A(추가) y, s : 암호문의 맨 뒤에 y개의 숫자를 덧붙인다. s는 덧붙일 숫자들이다. [ ex) A 2 421257 796813 ]

위의 규칙에 맞게 작성된 명령어를 나열하여 만든 문자열이 주어졌을 때, 암호문을 수정하고, 수정된 결과의 처음 10개 숫자를 출력하는 프로그램을 작성하여라.

[입력]
첫 번째 줄 : 원본 암호문의 길이 N ( 2000 ≤ N ≤ 4000 의 정수)
두 번째 줄 : 원본 암호문
세 번째 줄 : 명령어의 개수 ( 250 ≤ M ≤ 500 의 정수)
네 번째 줄 : 명령어
위와 같은 네 줄이 한 개의 테스트 케이스이며, 총 10개의 테스트 케이스가 주어진다.

[출력]
#기호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 수정된 암호문의 처음 10개 항을 출력한다.

[제약 사항]
실행 시간 60ms 이하

for t in range(1, 11) :
    N = int(input())
    code = list(map(int, input().split()))
    M = int(input())
    instruction = list(input().split())

    ins = []
    for i in range(len(instruction)) :
        if instruction[i] == "I" or instruction[i] == "D" or instruction[i] == "A":
            if i != 0 :
                ins.append(tmp)
            tmp = [instruction[i]]
        elif i == len(instruction)-1 :
            tmp.append(instruction[i])
            ins.append(tmp)
        else :
            tmp.append(instruction[i])

    for i in range(M) :
        if ins[i][0] == "I" :
            x = int(ins[i][1])
            y = int(ins[i][2])
            s = ins[i][3:]
            for j in range(y) :
                code.insert(x+j, int(s[j]))
        elif ins[i][0] == "D" :
            x = int(ins[i][1])
            y = int(ins[i][2])
            for j in range(y) :
                del(code[x])
        elif ins[i][0] == "A" :
            y = int(ins[i][1])
            s = ins[i][2:]
            for j in range(y) :
                code.append(int(s[j]))

    print("#{} {} {} {} {} {} {} {} {} {} {}".format(t, *code))

1234. [S/W 문제해결 기본] 10일차 - 비밀번호

평소에 잔머리가 발달하고 게으른 철수는 비밀번호를 기억하는 것이 너무 귀찮았습니다. 적어서 가지고 다니고 싶지만 누가 볼까봐 걱정입니다. 한가지 생각을 해냅니다.
0~9로 이루어진 번호 문자열에서 같은 번호로 붙어있는 쌍들을 소거하고 남은 번호를 비밀번호로 만드는 것입니다.
번호 쌍이 소거되고 소거된 번호 쌍의 좌우 번호가 같은 번호이면 또 소거 할 수 있습니다.
예를 들어 아래의 번호 열을 철수의 방법으로 소거하고 알아낸 비밀 번호입니다.

[입력]
10개의 테스트 케이스가 10줄에 걸쳐, 한 줄에 테스트 케이스 하나씩 제공된다.
각 테스트 케이스는 우선 문자열이 포함하는 문자의 총 수가 주어지고, 공백을 둔 다음 번호 문자열이 공백 없이 제공된다.
문자열은 0~9로 구성되며 문자열의 길이 N은 10≤N≤100이다. 비밀번호의 길이는 문자열의 길이보다 작다.

[출력]
#부호와 함께 테스트 케이스의 번호를 출력하고, 공백 문자 후 테스트 케이스에 대한 답(비밀번호)을 출력한다.

for test_case in range(1, 11):
    n, s = input().split()
    stack = [s[0]]

    for i in range(1, int(n)):
        if len(stack) != 0 and stack[-1] == s[i]:
            stack.pop()
        else:
            stack.append(s[i])

    print(f"#{test_case} {''.join(map(str, stack))}")
profile
This is a velog that freely records the process I learn.

0개의 댓글