본문 바로가기

코딩테스트/파이썬 알고리즘 문제풀이 입문

탐색 & 시뮬레이션

회문 문자열 검사숫자만 추출

 

아이디어 및 구체적 풀이

입력값 N(입력받을 단어 갯수)

단어 입력받고 대문자로 바꾸기

입력받은 단어의 길이사용해서 양대칭으로 비교

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")
N = int(input())

for i in range(N):
    a = input()
    a = list(a.upper())

    b = len(a) // 2
    for j in range(b):
        if a[j] != a[-1 - j]:
            print("#%d NO" % (i + 1))
            break
        else:
            print("#%d YES" % (i + 1))
            break

 

 

고찰

입력받은 문자열의 길이의 변수명을 주는것에 대해 주의하자 !

반복문과 조건분기 처리에서도 흐름을 잘 보자 나머진 이상무

 

숫자만  추출

아이디어 및 구체적 풀이

입력 값을 문자 그대로 받아 반복문을 사용하여 isdigit으로 숫자를 찾는다.

 

 

내가 짠 코드

import sys
sys.stdin = open("input.txt", "r")
a = list(input())
num_list = []

res = 0
for i in range(len(a)):
    if a[i].isdigit():
        num_list.append(a[i])

num = "".join(str(num) for num in num_list)
int_num = int(num)
print((int_num))

cnt = 0
for i in range(1, int_num + 1):
    if int_num % i == 0:
        cnt += 1

print(cnt)

 

 

 

 

모범답안

 

내가 짠 코드

 

 

고찰

입력 받은 문자를 숫자로 바꾸는 동시에 앞에 0이 오는 로직을 처리 한 모범 답안 코드가 훨씬 나은것같다.

res=res*10 +res는 자주 나오는 로직이니 외우도록 해야겠다.

 

 

카드 역배치

아이디어 및 구체적 풀이

입력값 역순으로 바꿀 각 인덱스 값 10개

1. 반복문을 돌며 해당 인덱스와 해당인덱스 사이의 값들을 swap

 

 

 

 

 

모범답안

 

 

내가 짠 코드

import sys
sys.stdin = open("input.txt", "r")

card = list(range(21))

for _ in range(10):
    a, b = map(int, input().split(" "))
    for i in range((b - a + 1) // 2):
        card[a + i], card[b - i] = card[b - i], card[a + i]

print(card)

고찰

모범 답안과 접근법 동일

출력 까지 생각못하고 다 짠줄암 ㅋㅋ;
출력문 pop도 떠올려야했는데 그래도 접근 잘해서 만-족

 

 

 

 

리스트 합치기       풀이 다시 보기

A

 

 

아이디어 및 구체적 풀이

입력값 N(첫번쨰 리스트의 크기) M(두번째 리스트의 크기

1. 각 리스트를 합쳐 sort함수 사용

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")

N = int(input())
a = list(map(int, input().split(" ")))
M = int(input())
b = list(map(int, input().split(" ")))


print(a + b)
c = a + b
c.sort()

print(c)

 

 

고찰

우선 결과 값은 제대로 나오게 하였다.

하지만 모범 답안은 sort를 사용하지 않았다. 시간복잡도 떄문이다. sort를 사용하면 8log8이 나온다.

하지만 모범 답안대로면 시간복잡도 N으로 코드를 짤수 있다.

다음엔 이런 접근으로 시도해 봐야겠다.  포인터 사용

 

수들의 합

 

아이디어 및 구체적 풀이

입력값 N(입력 개수) M( i~j까지 합)

1.p1,p2인덱스 포인터를 활용

2. while문의 브레이크 조건 ==> p1 ==(N-1) and p2==(N-1) 

 

 

 

 

 

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")

N, M = map(int, input().split(" "))
a = list(map(int, input().split(" ")))


p1 = 0
p2 = 1
cnt = 0
print(p1, p2)

while p1 != (N - 1):
    if sum(a[p1:p2]) == M:
        //print("1", p1, p2)
        cnt += 1
        p1 += 1
        //print("cnt")
    elif sum(a[p1:p2]) < M:
        //print("2", p1, p2)
        p2 += 1

    elif sum(a[p1:p2]) > M:
       //print("3", p1, p2)
        p1 += 1

print(cnt)

 

 

고찰

모범 답안과 접근은 약간 다르지만 거진 비슷한것 같다.

직관적으로 슬라이싱 연산을한 내가 짠 코드가 더 나은것 같다.

 

 

 

격자판 최대합

 

아이디어 및 구체적 풀이

입력값 N (격자판수)
1. 반복문을 이용하여 리스트 하나씩 인덱스를 이동하며 비교

 

 

 

 

 

 

 

 

 

 

 

 

모범답안

 

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")
N = int(input())
a = [list(map(int, input().split(" "))) for _ in range(N)]
for i in range(N):
    print(a[i])

Max = 0
for i in range(N):
    sum1 = sum2 = 0
    for j in range(N):
        sum1 = sum1 + a[i][j]
        sum2 = sum2 + a[j][i]
        if Max < sum1:
            Max = sum1
        if Max < sum2:
            Max = sum2
sum1 = 0
for i in range(N):
    sum1 = sum1 + a[i][i]
    if Max < sum1:
        Max = sum1

sum1 = 0
for i in range(N):
    sum1 = sum1 + a[i][N - i - 1]
    if Max < sum1:
        Max = sum1
print(Max)

 

고찰

접근법과 풀이 거의 비슷하다.

하지만 나는 대각선을 비교하는 로직에서는 반복문을 따로 떼었다.

그냥 생각 없이 코드를 짜서 그런것 같다. 

코드를 짠뒤 답이 나오더라도  묶을 수 있는게 있는지 리팩토링을 거쳐야겠다.

 

 

 

사과나무

아이디어 및 구체적 풀이

입력값 N (격자판수)

반복문을 사용하여 인덱스 계산을 통해 조건대로 더한다.

 

 

 

 

 

 

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")
N = int(input())
a = [list(map(int, input().split(" "))) for _ in range(N)]
for i in range(N):
    print(a[i])

sum = 0

for i in range(N // 2 + 1):
    for j in range(N // 2 - i, N // 2 + 1 + i):
        sum = sum + a[i][j]
for i in range(N // 2 + 1, N):
    for j in range(i - N // 2, N + N // 2 - i):
        print(a[i][j])
        sum = sum + a[i][j]


print(sum)

고찰

나는 크게 두부분으로 나누어 모양대로 더하였다.

그 과정에서 리스트 슬라이싱 연산에 대해 생각하는 시간이 꽤나 들었다.

반면에 모범답안은 생각 하지 못한 변수로 슬라이싱을 진행하여 직관적으로 더 좋은 코드를 짠것같다.

 

시작과 양끝을 변수로 사용하여 슬라이싱 연산을 하는것을 기억해야겠다.

 

 

 

 

곳감(모래시계)

아이디어 및 구체적 풀이

입력값 N(격자판 개수) M(회전명령수)      x(1부터 시작하는 행수),    y(0이면 왼쪽 밀기, 1이면 오른쪽 밀기),     z(미는 횟수)

 

1. 반복문을 사용하여 미는 로직 떠올리기

2. 미는 로직 ==>

3. 아 인덱스 0번째 채워주는걸 해야할듯=> 아 아니네 그냥 해도됨

 

 

 

 

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")
N = int(input())
a = [list(map(int, input().split(" "))) for _ in range(N)]
M = int(input())


for _ in range(M):
    x, y, z = map(int, input().split(" "))
    x = x - 1
    if y == 0:
        a[x] = a[x][z:] + a[x][:z]
    elif y == 1:
        a[x] = a[x][-z:] + a[x][:-z]

s = 0
e = N
sum = 0
for i in range(N):
    for j in range(s, e):
        sum = sum + a[i][j]
    if i < N // 2:
        s = s + 1
        e = e - 1
    elif i >= N // 2:
        s = s - 1
        e = e + 1
print(sum)

 

고찰

왼쪽 밀기와 오른쪽 밀기에 대한 슬라이싱 연상에 대해 고민하는 시간이 길었다.

문제를 풀수록 아직 리스트와  슬라이싱 연산 능력이 부족한것 같다. 더 많은 연습과 복습을 해야겠다.

 

또한 모범답안의 append와 pop보다 그냥 내가 짠 코드가 더 간결하게 보기 좋은것 같다. 이상

 

 

 

 

 

봉우리

 

아이디어 및 구체적 풀이

입력값 N (걱자판의 개수)

1. 0으로 채워진 테두리 채우기

2.x,y를 0,1로 채워진 리스트로 잡고 상하좌우 값과 하나씩 반복문을 돌며 비교한다.

 

 

 

 

 

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")
N = int(input())
a = [list(map(int, input().split(" "))) for _ in range(N)]

for i in range(N):
    a[i].append(0)
    a[i].insert(0, 0)


front_xero = [0] * (N + 2)
back_xero = [0] * (N + 2)
a.append(front_xero)
a.insert(0, front_xero)

x = [0, 1, 0, -1]
y = [1, 0, -1, 0]

cnt = 0
cnt_4 = 0
for i in range(1, N + 1):
    for j in range(1, N + 1):
        cnt_4 = 0
        for k in range(4):
            if a[i][j] > a[i + y[k]][j + x[k]]:
                cnt_4 = cnt_4 + 1
                if cnt_4 == 4:
                    cnt += 1
                    print(a[i][j], i, j)

print(cnt)

 

고찰

0 테투리 만드는 로직은 조금 다르지만 비슷한것 같다 하지만 모범 답안이 더 깔끔하게 잘 짠것같다. 숙지 해야겠다.

또한 상하좌우를 비교하는 로직에서도 큰 차이 없이 잘 진행 하였다.

하지만 all이라는 함수를 쓴 모범 답안이 역시 코드가 더 간결하고 깔끔하다. 이또한 여러번 비교하며 체크 변수를 하나더

선언하는것보다 all 함수를 쓰는것을 숙지해야겠다.

 

 

 

스토쿠 검사

아이디어 및 구체적 풀이

각 행마다 1~9가 모두 있는지 확인

각 열 마다 1~9가 모두 있는지 확인

3x3사각형에 모두 1~9까지 있는지 확인

 

0으로 채워진 9 크기의 리스트를 생성하고

각 행을 돌며 그 값에 맞는 빈리스트의 인덱스를 1 로 변경

그리고 그 빈리스트에서 채워진 리스트의 합sum함수를 사용해서 9면 통과 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

모범답안

내가 짠 코드

import sys

sys.stdin = open("input.txt", "r")

a = [list(map(int, input().split(" "))) for _ in range(9)]


# 행,열체크
for i in range(9):
    b = [0] * 10
    c = [0] * 10
    for j in range(9):
        b[a[i][j]] = 1
        c[a[j][i]] = 1

    if sum(b) != 9 or sum(c) != 9:
        print("No")

for s in range(3):
    for e in range(3):
        d = [0] * 10
        for i in range(3):
            for j in range(3):
                d[a[s * 3 + i][e * 3 + j]] = 1
        if sum(c) != 9:
            print("No")

 

고찰

어우 머리 아파..

기본적인 접근 법은 비슷하였다.

하지만 모범 답안은 함수로 구현하여 출력 값을 더 좋게 출력하였고

난 확인만 하는 코드를 짰다.

출력 문에서 막힐시 함수형으로 구현하는 것도 고려를 잘해봐야겠다.

 

 

 

격자판 회문수

 

 

아이디어 및 구체적 풀이

 

 

 

 

 

 

 

모범답안

내가 짠 코드

 

 

 

고찰