문제

 

내가 작성한 코드
from collections import deque
import sys
input = sys.stdin.readline

# N, M, V
n, m, v = map(int, input().split())
graph = [ [] for i in range(n+1)]

for i in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
 
for i in graph:
    if not i:
        continue
    else:
        i = i.sort()

def dfs(graph, v, visited):
    visited[v] = True
    print(v, end= ' ')
    for i in graph[v]:
        if not visited[i]:
            dfs(graph, i, visited)
            
def bfs(graph, start, visited):
    queue = deque([start])
    visited[start]= True
    while queue:
        v = queue.popleft()
        print(v, end = ' ')
        for i in graph[v]:
            if not visited[i]:
                queue.append(i)
                visited[i] = True
                
visited = [False] * (n + 1)
dfs(graph, v, visited)
print()
visited = [False] * (n + 1)
bfs(graph, v, visited)

 

코드 설명
from collections import deque
import sys
input = sys.stdin.readline

> 큐를 사용하기 위해서 deque 모듈을 불러왔고, 빠른 데이터 입력을 위해서 sys 모듈을 불러왔습니다.

> input = sys.stdin.readline 코드는 데이터를 빠르게 입력할 수 있는 코드입니다.

 

n, m, v = map(int, input().split())
graph = [ [] for i in range(n+1)]

> n, m, v 변수는 정점의 개수, 간선의 개수, 탐색을 시작할 정점의 번호를 의미하는 변수입니다.

> graph 변수는 정점끼리 연결된 그래프 정보를 의미하는 변수입니다.

> [ [] for i in range(n+ 1) ] 로 코드를 작성한 이유는 정점의 수는 1부터 시작하기 때문에 range(n + 1)로 기존의 길이보다 1을 추가해서 빈 리스트를 만들었습니다.

 

for i in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

> 간선의 개수만큼 반복문을 진행하기 위해서 for문을 사용했습니다.

> a, b는 연결되는 정점을 의미하는 각 정점입니다.

> 여기부분에서 굉장히 에러가 많이 발생했습니다.

> 처음에 graph[a].append(b) 만 작성하고 아래 graph[b].append(a)는 작성하지 않았습니다.

> 이렇게 되면 단방향 그래프가 되는데 예제 입력 2에서 에러가 계속 발생하게 됩니다.

> 양방향 그래프를 만들어주기 위해서 graph[b].append(a) 코드를 추가로 작성을 해주었습니다.

 

for i in graph:
    if not i:
        continue
    else:
        i = i.sort()

> 예제 출력에서 보시면 각 정점에서의 출력이 오름차순으로 출력됨을 인지할 수 있습니다.

> 그러므로, 각 정점에서 연결된 정점들을 오름차순으로 정렬해주기 위해서 반복문 for문을 사용하였습니다.

 

def dfs(graph, v, visited):
    visited[v] = True
    print(v, end= ' ')
    for i in graph[v]:
        if not visited[i]:
            dfs(graph, i, visited)
            
def bfs(graph, start, visited):
    queue = deque([start])
    visited[start]= True
    while queue:
        v = queue.popleft()
        print(v, end = ' ')
        for i in graph[v]:
            if not visited[i]:
                queue.append(i)
                visited[i] = True

> 이 dfs, bfs 코드는 '이것이 코딩테스트다' 책에서 나온 코드를 그대로 외워서 작성했습니다. 이런건 외우는거 밖에 답이 없는거 같습니다 ㅜㅜ

 

visited = [False] * (n + 1)
dfs(graph, v, visited)
print()
visited = [False] * (n + 1)
bfs(graph, v, visited)

> 그 다음 visited 변수는 각 정점이 방문을 했으면 True로 바꿔주면서 갔던 곳을 다시 가지 않게 하기 위한 변수입니다.

> 또 여기서 에러가 발생한게 있습니다.

> print(dfs(graph, v, visited)) 로 코드를 작성하면 마지막에 None 이 출력되게 됩니다. 그 이유는 dfs 함수를 보시면 return 값이 존재하지 않기 때문에 그런거라고 합니다. 주의!!

 

문제

 

내가 작성한 코드
import sys
input = sys.stdin.readline

# 파일의 개수 N 입력
n = int(input())
file_dict = {}

for i in range(n):
    file_n = input().split('.')[1].replace('\n', '')
    if file_n not in file_dict.keys():
        file_dict[file_n] = 1
    else:
        file_dict[file_n] += 1
        
result = sorted(list(file_dict.keys()))

for i in result:
    print(i + ' ' + str(file_dict[i]))

 

코드 설명
import sys
input = sys.stdin.readline

> 'sys.stdin.readline' 코드는 데이터를 빠르게 입력할 수 있는 코드입니다. 대량의 데이터를 입력받아야 하는 문제일 때를 대비해서 항상 작성하고 있습니다.

 

n = int(input())
file_dict = {}

> 변수 n 은 파일의 개수를 받기 위한 변수입ㄴ디ㅏ. 

> file_dict 변수는 파일의 확장자별 수를 저장하기 위해서 빈 dict 자료형을 만들었습니다.

 

for i in range(n):
    file_n = input().split('.')[1].replace('\n', '')
    if file_n not in file_dict.keys():
        file_dict[file_n] = 1
    else:
        file_dict[file_n] += 1

> 파일의 개수만큼 파일을 받기 위해서 for문을 사용하였습니다.

> 파일이 'sbrus.txt' 와 같이 들어오는데 이 중에 필요한 'txt' 와 같은 확장자명입니다.

> 그래서 input().split('.')[1] 을 사용하면 결과가 ['sbrus', 'txt\n'] 으로 나오는데 그 뒤에 나오는 값을 추출한 것이다.

> 처음에 input().split('.')[1]을 하면 'txt'로만 나오는 줄 알았는데 'txt\n'으로 결과가 나와서 놀랐다.

> 그래서 replace('\n', '')을 사용해서 '\n' 을 제거해주었다.

> 그리고 if-else문을 사용해서 file_dict.keys()에 확장자명이 없다면 file_dic[file_n] = 1로 설정해주고, 있다면 file_dict += 1로 설정해주었습니다.

> 이렇게 하면 확장자별 수를 file_dict 변수에 담을 수 있게 됩니다.

 

result = sorted(list(file_dict.keys()))

> 확장자 이름을 사전순으로 출력해야 하므로, sorted(list(file_dict.keys())) 를 사용해서 확장자명만 추출해서 오름차순으로 정렬된 값을 result 변수에 담았습니다.

 

for i in result:
    print(i + ' ' + str(file_dict[i]))

> 확장자 이름이 사전순으로 정렬된 변수 result를 for문을 사용해서 사전순으로 출력시켰습니다.

> 원하는 출력값에 맞게 print(i, file_dict[i]) 를 사용해서 확장자명과 확장자 파일의 개수를 출력시켰습니다.

문제

 

참고한 코드
import sys
# pypy3 해결.. python(3%) 시간초과


# 대각선의 퀸이 있는지 확인
def check(x):
    for i in range(x):
        if abs(graph[x] - graph[i]) == x - i:
            return False
    return True


# 체스 판의 열을 dfs 탐색
def dfs(queen):
    global res

    # n번째 퀸을 놓으려 한다면 리턴 (n개의 퀸을 놓았기 때문.)
    if queen == n:
        res += 1 # 방법의 수 카운트
        return

    # 모든 체스판의 열을 확인
    for i in range(n):
        # i 번째 열의 퀸을 놓지 않았다면
        if not visited[i]:
            graph[queen] = i # (queen, i)에 퀸을 둔다.

            # 대각선의 겹치는 퀸이 있는지 확인
            if check(queen):
                # 백 트래킹
                visited[i] = True # 퀸을 놓는다.
                dfs(queen + 1) # 재귀적으로 퀸을 놓을 수 있는 열을 찾는다.
                visited[i] = False # 재귀 탐색 후 퀸을 n개 놓을 수 없다면 퀸을 놓지 않는 것으로 초기화 후 다른 열을 탐색


n = int(sys.stdin.readline())
graph = [0 for _ in range(n)] # n번째 열의 퀸의 위치
visited = [False for _ in range(n)] # 체스판의 탐색 여부
res = 0 # 퀸을 놓는 방법의 수

dfs(0)
print(res)

> 참고한 블로그

https://fre2-dom.tistory.com/247

 

[baekjoon] 백준 9663번(파이썬): N-Queen

문제 9663번: N-Queen N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오. www.acmicpc.net

fre2-dom.tistory.com

> 와.... 진짜 어렵다 ㅜㅜ

 

내가 해석한 코드 설명
def check(x):
    for i in range(x):
        if abs(graph[x] - graph[i]) == x - i:
            return False
    return True

> 이 코드는 대각선의 퀸이 있는지 확인하는 코드이다. 일단 퀸은 상하좌우 대각선 모두 움직일 수 있다.

> for문을 사용해서 x의 길이만큼 반복문을 진행한다.

> abs(graph[x] - graph[i]) == x - i 의 의미는 두 값이 같게 된다면 대각선이라는 의미이다. 솔직히 아직도 이해가 잘안됐닼ㅋㅋ

> 반복문을 통과한다면 True, 아니면 False

 

# 체스 판의 열을 dfs 탐색
def dfs(queen):
    global res

    # n번째 퀸을 놓으려 한다면 리턴 (n개의 퀸을 놓았기 때문.)
    if queen == n:
        res += 1 # 방법의 수 카운트
        return

    # 모든 체스판의 열을 확인
    for i in range(n):
        # i 번째 열의 퀸을 놓지 않았다면
        if not visited[i]:
            graph[queen] = i # (queen, i)에 퀸을 둔다.

            # 대각선의 겹치는 퀸이 있는지 확인
            if check(queen):
                # 백 트래킹
                visited[i] = True # 퀸을 놓는다.
                dfs(queen + 1) # 재귀적으로 퀸을 놓을 수 있는 열을 찾는다.
                visited[i] = False # 재귀 탐색 후 퀸을 n개 놓을 수 없다면 퀸을 놓지 않는 것으로 초기화 후 다른 열을 탐색

> res 변수는 경우의 수를 알려주는 결과값 변수이다.

> 어렵다 ㅜㅜ 

문제

 

내가 작성한 코드
# N, M 입력
n, m = map(int, input().split())
s = []

def dfs():
    if len(s) == m:
        print(' '.join(map(str, s)))
        return
    for i in range(1, n + 1):
        s.append(i)
        dfs()
        s.pop()

dfs()

> 처음으로 백트래킹 맞췄다!!!

> 점점 감을 잡아가는 듯!!!

 

코드 설명
n, m = map(int, input().split())
s = []

> 여기는 N과 M 값을 받는 변수이고, s 라는 빈 리스트를 생성해서 값을 출력시키기 위한 리스트입니다.

 

def dfs():
    if len(s) == m:
        print(' '.join(map(str, s)))
        return
    for i in range(1, n + 1):
        s.append(i)
        dfs()
        s.pop()

> 이번 N과 M 문제는 중복되는 값이 나와도 될 뿐만 아니라, 같은 수가 나와도 된다는 점입니다.

> 이전에는 for 문 안에 if i not in s : 라는 if 문을 사용해서 같은 수를 제거하기 위한 코드를 작성했었는데, 이번에는 같은 수가 나와야 되므로 if문을 제거해주었습니다.

> 나머지는 코드는 모두 같습니다!!

문제

 

참고한 코드
n,m = list(map(int,input().split()))
s = []
def dfs(start):
    if len(s)==m:
        print(' '.join(map(str,s)))
        return
    
    for i in range(start,n+1):
        if i not in s:
            s.append(i)
            dfs(i+1)
            s.pop()
dfs(1)

> 참고한 블로그

https://jiwon-coding.tistory.com/22

 

[백준] 15650번 N과 M(2) / 파이썬(python)

# 문제 링크 www.acmicpc.net/problem/15650 15650번: N과 M (2) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야

jiwon-coding.tistory.com

 

 

내가 해석한 코드 설명
n,m = list(map(int,input().split()))
s = []

> 여기느 N과 M (1) 과 동일하다.

 

def dfs(start):
    if len(s)==m:
        print(' '.join(map(str,s)))
        return
    
    for i in range(start,n+1):
        if i not in s:
            s.append(i)
            dfs(i+1)
            s.pop()

> N과 M(1)과 달라진 점은 start 초기값이 생겼다는 것이다.

> 그 이유는 중복되는 값이 없어야될 뿐만 아니라, 오름차순으로 출력해야 되기 때문이다.

> 그러므로 start 변수가 for문에 range(start, n +1)로 들어감으로써 중복되는 것을 없애줄뿐만 아니라, 자신보다 작은 값은 포함을 시키지않게 된다!!

> 너무 어렵다 ㅜㅜ

문제

 

참고한 코드
n, m = map(int, input().split())

s= []

def dfs():
    if len(s) == m:
        print(' '.join(map(str, s)))
        return
    for i in range(1, n+1):
        if i not in s:
            s.append(i)
            dfs()
            s.pop()
            
dfs()

> 참고한 블로그

https://jamesu.dev/posts/2020/04/13/baekjoon-problem-solving-15649/

 

백준 문제 풀이: 15649 - N과 M (1)

Dev Blog by James Minsu Jeon

jamesu.dev

> join 함수에 관한 블로그

https://blockdmask.tistory.com/468

 

[python] 파이썬 join 함수 정리 및 예제 (문자열 합치기)

안녕하세요. BlockDMask입니다. 오늘은 파이썬에서 리스트를 문자열로 일정하게 합쳐주는 join 함수에 대해서 알아보려고 합니다. join 함수는 문자열을 다룰 때 유용하게 사용할 수 있는 함수이니

blockdmask.tistory.com

> 이번에 join 함수와 백트래킹에 대한 의미를 알아보았다!!!

 

내가 해석한 코드 설명
n, m = map(int, input().split())
s= []

> n, m 은 자연수 N, M을 받을 변수입니다.

> s 변수는 값을 출력하기 위한 빈 리스트입니다.

 

def dfs():
    if len(s) == m:
        print(' '.join(map(str, s)))
        return
    for i in range(1, n+1):
        if i not in s:
            s.append(i)
            dfs()
            s.pop()

> 먼저 if문을 사용하여 s 변수의 길이가 m 변수와 같다면 ' '.join(map(str, s)) 을 추출하도록 되어있다.

> 이 의미는 s 변수는 m개의 값만큼의 길이일 때마다 값을 추출해야하기 때문이다.

> 그리고 s 변수는 리스트로서 join 함수를 사용하면 join 앞에 있는 문자열이 각 리스트의 값 사이에 들어가게 된다.

> 예제 출력을 보면 각 값은 빈 칸을 두고 출력되기 때문에 ' '.join 함수를 사용한 것이다.

> 그리고 for 문(반복문)을 range(1, n +1) 범위만큼 사용하고 dfs 를 사용하여 s 변수에 같은 값이 존재하지 않으면 s 변수에 값을 추가하고, 그와 동시에 재귀함수를 사용하여 dfs() 를 다시 적용시킨다.

> 처음에 이해가 잘가지 않았는데, 이렇게 하면 s 변수에 들어간 값을 통해 얻을 수 있는 값들은 전부 얻고 나오게 된다.

> 그리고 다시 그 값을 pop() 함수를 통해 빼주면서 반복된 값을 없게 해준다.

 

문제

 

내가 작성한 코드
# 정수 K 입력
k = int(input())
v_l = []

for i in range(k):
    v = int(input())
    if v == 0:
        v_l.pop()
        continue
    else:
        v_l.append(v)
try:
    print(sum(v_l))
except:
    print(0)

 

코드 설명
k = int(input())
v_l = []

> k는 K개의 줄을 입력받아야 하는 값을 입력받았다.

> v_l 변수는 결과 출력하기 위한 빈 리스트입니다.

 

for i in range(k):
    v = int(input())
    if v == 0:
        v_l.pop()
        continue
    else:
        v_l.append(v)

> for문(반복문)을 k 길이만큼 사용하여, 값을 v 변수에 담게 했습니다.

> if - else 문을 사용하여 v 값이 0이라면 v_l 변수에 값을 빼주기 위해 v_l.pop() 함수를 사용해주었습니다.

> 그리고, 바로 다음 반복문으로 넘어가기 위해 continue 를 작성했습니다.

> v 값이 0이 아니라면, v_l 변수에 v 값을 append 시켜주었습니다.

 

try:
    print(sum(v_l))
except:
    print(0)

> try - except 문을 사용하여 오류발생할 시를 대비했습니다.

> try 문에는 최종 출력값인 v_l 변수의 합을 출력하기 위해서 sum(v_l) 함수를 적용하였습니다.

> except문에는 print(0)을 해주었는데, 그 이유는 리스트가 빌 때는 sum() 함수를 적용하면 에러가 발생하지 않을까 싶어 print(0) 을 해주었습니다.

문제

 

내가 작성한 코드
# 방 번호 N 입력
n = input()
n_l = [int(i) for i in n]
v = [0] * 10

for n in n_l:
    if (n ==9 and v[n] > v[6]):
        v[6] += 1
        continue
    if (n ==6 and v[n] > v[9]):
        v[9] += 1
        continue
    v[n] += 1


print(max(v))

 

코드 설명
n = input()
n_l = [int(i) for i in n]
v = [0] * 10

> 숫자 n을 입력받는데, input() 함수로 입력받으면 문자로 입력된다. 그리고, n_l 변수는 list compression 을 사용하여 숫자를 하나씩 분리하여 담은 리스트입니다. 이렇게 한 이유는 각 숫자의 개수를 세기 위해서입니다.

> 어쩌면 이 방식은 계수 정렬에서 아이디어를 얻었습니다.

> v는 n_l 변수에 담은 숫자 n의 각 숫자 0~9의 개수를 각각 세기 위한 변수입니다.

 

for n in n_l:
    if (n ==9 and v[n] > v[6]):
        v[6] += 1
        continue
    if (n ==6 and v[n] > v[9]):
        v[9] += 1
        continue
    v[n] += 1

> for문(반복문)을 사용하여 n_l 변수에 담겨져있는 숫자를 하나씩 추출하면서 v[n] 변수에 담아줍니다.

> 이 과정에서 6과 9는 같이 사용할 수 있기 때문에, if문을 두 번사용하여 n==9 and v[n] > v[6] 과 같은 코드를 사용하여 n이 9인데 9의 개수 v[n]과 6의 개수 v[6] 을 비교할 때 v[9]가 더 크다면 v[6]의 값을 넣어주기 위해 if 문을 사용하였습니다.

> 그리고 continue 문을 사용하여 아래의 v[n] += 1을 적용하지 않고 바로 다음 for문으로 넘어가기 위해서 적용하였습니다. 

> continue문을 사용하지 않으면 정답이 추출되지 않습니다.

 

print(max(v))

> 마지막으로 max(v)를 해주면 우리가 원하는 필요한 세트의 개수를 구할 수 있습니다

+ Recent posts