coding test

[파이썬] 4861. 회문

잔망루피 2021. 1. 8. 19:23

swexpertacademy.com/main/learn/course/lectureProblemViewer.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

※ SW Expert 아카데미의 문제를 무단 복제하는 것을 금지합니다.

ABBA처럼 어느 방향에서 읽어도 같은 문자열을 회문이라 한다. NxN 크기의 글자판에서 길이가 M인 회문을 찾아 출력하는 프로그램을 만드시오.

회문은 1개가 존재하는데, 가로 뿐만 아니라 세로로 찾아질 수도 있다.

 

예를 들어 N=10, M=10 일 때, 다음과 같이 회문을 찾을 수 있다.
 

G

O

F

F

A

K

W

F

S

M

O

Y

E

C

R

S

L

D

L

Q

U

J

A

J

Q

V

S

Y

Y

C

J

A

E

Z

N

N

Z

E

A

J

W

J

A

K

C

G

S

G

C

F

Q

K

U

D

G

A

T

D

Q

L

O

K

G

P

F

P

Y

R

K

Q

T

D

C

X

B

M

Q

T

I

O

U

N

A

D

R

P

N

E

T

Z

Z

A

T

W

D

E

K

D

Q

F

  

[입력]
 

첫 줄에 테스트 케이스 개수 T가 주어진다.  1≤T≤50

다음 줄부터 테스트케이스의 첫 줄에 N과 M이 주어진다. 10≤N≤100, 5≤M≤N

다음 줄부터 N개의 글자를 가진 N개의 줄이 주어진다.

 

[출력]
 

각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다.

입력 출력
3
10 10
GOFFAKWFSM
OYECRSLDLQ
UJAJQVSYYC
JAEZNNZEAJ
WJAKCGSGCF
QKUDGATDQL
OKGPFPYRKQ
TDCXBMQTIO
UNADRPNETZ
ZATWDEKDQF
10 10
WPMACSIBIK
STWASDCOBQ
AMOUENCSOG
XTIIGBLRCZ
WXVSWXYYVU
CJVAHRZZEM
NDIEBIIMTX
UOOGPQCBIW
OWWATKUEUY
FTMERSSANL
20 13
ECFQBKSYBBOSZQSFBXKI
VBOAIDLYEXYMNGLLIOPP
AIZMTVJBZAWSJEIGAKWB
CABLQKMRFNBINNZSOGNT
NQLMHYUMBOCSZWIOBINM
QJZQPSOMNQELBPLVXNRN
RHMDWPBHDAMWROUFTPYH
FNERUGIFZNLJSSATGFHF
TUIAXPMHFKDLQLNYQBPW
OPIRADJURRDLTDKZGOGA
JHYXHBQTLMMHOOOHMMLT
XXCNJGTXXKUCVOUYNXZR
RMWTQQFHZUIGCJBASNOX
CVODFKWMJSGMFTCSLLWO
EJISQCXLNQHEIXXZSGKG
KGVFJLNNBTVXJLFXPOZA
YUNDJDSSOPRVSLLHGKGZ
OZVTWRYWRFIAIPEYRFFG
ERAPUWPSHHKSWCTBAPXR
FIKQJTQDYLGMMWMEGRUZ
#1 JAEZNNZEAJ
#2 MWOIVVIOWM
#3 TLMMHOOOHMMLT

 

🔑 나의 풀이

 

T = int(input())
# 여러개의 테스트 케이스가 주어지므로, 각각을 처리합니다.
for test_case in range(1, T + 1):
    N, M=map(int, input().split())		# N= 글자 수 = 줄, M=회문의 길이
    lst=list()
    
    # 가로로 저장
    for i in range(N):
        lst.append(''.join(input()))
	
    # 세로로 저장
    c_lst=list()
    for c in range(N):			# 행
        copy=''
        for r in range(N):		# 열
            copy+=lst[r][c]		# 열 순회
        c_lst.append(copy)
     
    all_lst=lst+c_lst
    for x in all_lst:	# 가로, 세로 방향으로 모두 탐색
        i=0
        for y in range(N-M+1):
            if x[i:i+M] == x[i:i+M][::-1]:		# 회문이면 출력
                print(f"#{test_case} {x[i:i+M]}")
                break
            i+=1

 

가로, 세로 방향으로 문자열을 저장.

M의 길이만큼 리스트를 슬라이싱하고 회문이면 출력한다.

[::-1]은 리스트를 거꾸로 뒤집는다.

print(f"#{test_case} {''.join(lst[i])}")

print(f'#{test_case} {''.join(lst[i])}')는 잘못됨.

헐.. 지금까지 가로 또는 세로길이만큼 회문이 있는줄 알았는데 테스트케이스 3번은 예외네..

긴 문장 속에 숨어있네.

문제를 잘못 읽어서 글자 수가 N, 줄이 M인줄;

다시 코드를 짜서 완성 ㅎㅎ

 

👓 다른사람 풀이

 

T = int(input())

for t_idx in range(1, T+1):
    N, M = list(map(int, input().split()))		# N= 글자 수 = 줄, M=회문의 길이

    row_list = []
    for _ in range(N):
        row_list.append(input())
    
    col_list = []
    for c_idx in range(N):
        tmp = ''
        for r_idx in range(N):
            tmp += row_list[r_idx][c_idx]
        col_list.append(tmp)

    total_list = row_list + col_list
    for row in total_list:
        for idx in range(N):
            if M+idx > N:
                break
            s = row[idx:M+idx]
            if s == s[::-1]:
                print(f'#{t_idx} {s}')
                break

 

나랑 알고리즘이 같다.

N번 반복하면서 회문의 길이M+인덱스idx가 N보다 크면 break한다.

s에 회문의 길이만큼 값을 넣고 뒤집은 값s[::-1]과 비교해서 true면 출력하고 반복문을 끝낸다. 

 

def solution(input_list, m):
    n = len(input_list)
    count = n - m + 1
    for i in range(n):
        for c in range(count):
            j = 0
            while j < (m // 2):
                if input_list[i][c+j] != input_list[i][m+c-j-1]:
                    break
                j += 1
            if j == (m // 2):
                return "".join(input_list[i][c:c+m])

    for i in range(n):
        for c in range(count):
            j = 0
            result = []
            while j < (m // 2):
                if input_list[c+j][i] != input_list[m+c-j-1][i]:
                    break
                result.append(input_list[c+j][i])
                j += 1
            if j == m // 2:
                if m % 2:
                    middle = [input_list[c+j][i]]
                    result += middle + result[::-1]
                else:
                    result += result[::-1]
                return "".join(result)

def main():
    test_cases = int(input())
    for test_case in range(test_cases):
        input_list = []
        n, m = map(int, input().split())
        for _ in range(n):
            input_list.append(input())
        print(f"#{test_case + 1} {solution(input_list, m)}")


if __name__ == '__main__':
    main()

 

좀 복잡해보인다.

 

반응형

'coding test' 카테고리의 다른 글

[파이썬] 4869. 종이붙이기  (0) 2021.01.11
[파이썬] 4865. 글자수  (0) 2021.01.11
[파이썬] 4864. 문자열 비교  (0) 2021.01.08
[파이썬] 4843. 특별한 정렬  (0) 2021.01.08
[파이썬] 4839. 이진탐색  (0) 2021.01.07