Skip to content

HONGJOO/1월2주차/2문제#122

Merged
zaqquum merged 2 commits intoAlgorithmStudy-Allumbus:mainfrom
zaqquum:main
Jan 18, 2025
Merged

HONGJOO/1월2주차/2문제#122
zaqquum merged 2 commits intoAlgorithmStudy-Allumbus:mainfrom
zaqquum:main

Conversation

@zaqquum
Copy link
Collaborator

@zaqquum zaqquum commented Jan 12, 2025

🌱WIL

이번 한 주의 소감을 작성해주세요!

  • 지난주를 이어서 2주 동안 최종 플젝 시작하면서 알고리즘 문제 푸는데 많이 소홀했다. 담주부터는 최대한 아침 짬짬이라도 꾸준하게 풀도록 노력하겠다.

🚀주간 목표 문제 수: 2개

푼 문제


백준 #15654. N과 M (5): 백트래킹 / 실버3

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. 입력 변수 선언 및 초기화 하기
    • m개 수열 결과 저장할 배열 result
    • 원소 사용 여부 확인용 배열 check ,
    • N개의 원소 후보군들 저장 배열 element
  2. n개 수열 원소 후보군 오름차순 정렬하기
    • 사전순으로 수열 출력하기 위해 사전에 정렬함
  3. 순열 재귀 함수
    image

🚩제출한 코드

import sys

#0. 입력 받기 
N , M = map(int, sys.stdin.readline().split())
# M개의 수열 결과를 저장할 배열
result = [0 for _ in range(M)]
# 해당 원소 사용 여부 check 함수
check = [0 for _ in range(N)]
# n 개 수열 원소 후보군 저장하는 리스트
elements = list(map(int, sys.stdin.readline().split()))
#오름 차순 정렬 for 오름차순 결과 출력
elements.sort()
# print(elements)

# 1. m 개 수열 찾기 by 재귀 함수
def perm(m) : # m : result 안에 들어가있는 원소 개수 = 넣을 위치
    if m == M : # result  개수 같으면 = 재귀 종료 조건
        print(*result) # 출력

    else : 
        for i in range(N) : # 더 뽑아야 하면 , N 개 후보군 중에 확인
            if check[i] == 0 : #현재 후보원소(i) 사용 가능함
                result[m] = elements[i] # result에 등록
                check[i] = 1 # 사용중
                perm(m+1) # result 에 m+1 개 들어가 있음
                check[i] = 0  # 사용 완료

perm(0 )

💡TIL

배운 점이 있다면 입력해주세요

  • * 의 기능 : 튜플 , 리스트 unpacking

백준 #15652. N과 M (4): 백트래킹 / 실버3

정리한 링크: (바로가기)

🚩플로우 (선택)

코드를 풀이할 때 적었던 플로우가 있나요?

  1. check 를 mxn 의 행렬로 사용 여부 확인(중복 사용과 중복 수열 방지를 위해)
  2. 재귀 함수로 조건에 해당하는 함수 출력
    • 매개변수 m = result 에 들어간 원소들 개수 = 현재 들어갈 자리 수
      (1) m == M ,즉 result안에 M 개 들어가 있으면, 출력
      (2) m번째 자리에 n이 들어간 경험이 있는지 확인 - check[m][n-1] == 0
      -> 사용 가능
      조건 2 : 첫 result 원소면 바로 등록
      조건 3 : 아니면 , 이전 자리수에 등록된 result 원소 값보다 커야지 등록
      • 등록 시(result[m] = n) , check에도 사용 중 등록하기( check[m][n-1] = 1)
        (3)m+1 인 재귀 함수 수행
        (4) m 번째 자리 수에서 들어갈 1~N수 탐색 완료하면
        -> check[m] 은 모두 0으로 리셋하고, m-1 자리 수로 backtracking

🚩제출한 코드

import sys
N, M = map(int, sys.stdin.readline().split())
# 1. 변수 정의
result = [0 for _ in range(M)]
check= [[0 for _ in range(N)] for  i in range(M) ] # row : m번째 위치 , column  : N개 후보군 원소들의 m번째 자리수에 사용 여부


def perm(m) :
    if m == M : 
        print(*result)
    else : # m : 0,1,2 ...M-1
        for n in range(1, N+1) : 
            # print(f"before m : {m} /n {n} -> check {check[m]}")
            if check[m][n-1] == 0 : # 빈 자리 
                if (m == 0) or (m < M and n >= result[m-1]) :  # 첫번쨰 자리 등록 심사 -> pass
                    result[m] = n  # 사용 중     # 그외의 자리 등록 심사 -> 이전 자리수 <= 현재 자리수 조건 만족(중복 출력 방지)
                    check[m][n-1] = 1
                    # print(f"m : {m} /n {n} -> check {check[m]}")
                    # print(f"result { result}")
                    perm(m+1)

        # m 번째 자리에서 들어갈 1~N수 탐색 완료
        # 그러면 check[m] 은 0으로 리셋
        check[m] = [0 for j in range(N)]

perm(0)
                

💡TIL

배운 점이 있다면 입력해주세요

  • 순열 문제는 재귀함수로 Backtracking 적용!
    • 그외 세부 조건은 직접 그리면서 판단하자

@zaqquum zaqquum self-assigned this Jan 12, 2025
Copy link
Collaborator

@Mingguriguri Mingguriguri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

노션에 정리된 내용도 확인해보았는데, 정말 잘 정리하셨네요! 동작 과정과 문제 해결에 도움이 될 내용도 함께 포함되어 있어 보면서 '이렇게도 정리할 수 있구나' 하고 많이 배웠습니다! 😊

@zaqquum zaqquum merged commit 53dc481 into AlgorithmStudy-Allumbus:main Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants