dfs,bfs 관련 문제 풀고 익숙해지기
def dfs(start):
visited[start]=True
#start랑 연결되어 있는 컴퓨터 중에서
for i in connect[start]:
#방문 안했으면 그 컴퓨터를 시작으로해서 확인(점점 깊게)
if visited[i]==False:
dfs(i)
computers=int(input())
pair=int(input())
n=0
connect=[[]*computers for _ in range(computers+1)]
#바이러스의 방문여부 체크
visited=[False]*(computers+1)
for i in range(pair):
x,y=map(int,input().split())
#양방향 연결이니까
connect[x].append(y)
connect[y].append(x)
#1번 컴퓨터가 감염 됐을 경우
dfs(1)
#방문 했다 = 감염 됨
for virus in visited:
if(virus):
n+=1
#자기자신(1번 컴퓨터) 제외하고
print(n-1)
bfs 필요한거
1. 방문할 곳 저장해둘 공간(deque()이용)
2. 방문했는지 아닌지 check -> 방문한 곳을 또 방문할 필요없으니 전체 appartment에 표시해도 됨
from collections import deque
count=[]
def bfs(appartment,i,j):
n=len(appartment)
dx=[0,0,1,-1]
dy=[1,-1,0,0]
# 방문할 곳
visited=deque()
visited.append([i,j])
appartment[i][j]=0
count=1
while visited:
x,y=visited.popleft()
# 상하좌우
for pos in range(4):
nx=dx[pos]+x
ny=dy[pos]+y
# 범위 외
if nx<0 or nx>=n or ny<0 or ny>=n:
continue
# 단지번호 안 붙였으면 확인
if appartment[nx][ny]==1:
appartment[nx][ny]=0
visited.append([nx,ny])
# 번호 붙인거 갯수
count+=1
return count
N=int(input())
appartment=[]
for i in range(N):
appartment.append(list(map(int,input())))
for i in range(N):
for j in range(N):
if appartment[i][j]==1:
count.append(bfs(appartment,i,j))
# 오름차순으로 정렬
count.sort()
print(len(count))
for c in count:
print(c)
단지 번호 붙이기랑 다른점
from collections import deque
def bfs(map,i,j,h,w):
# 방문했는지 아닌지
visited=[[0]*w for _ in range(h)]
dx=[0,0,1,-1]
dy=[1,-1,0,0]
# 방문해야할 곳 queue에 저장
queue=deque()
queue.append((i,j,0))
visited[i][j]=1
distance=0
while queue:
x,y,d=queue.popleft()
for pos in range(4):
nx=dx[pos]+x
ny=dy[pos]+y
if nx>=h or nx<0 or ny>=w or ny<0:
continue
#방문도 안했고 육지일 때만
if map[nx][ny]=='L' and visited[nx][ny]==0:
visited[nx][ny]=1
# 한 칸 이동할 때마다 거리+1
queue.append((nx,ny,d+1))
distance=d+1
# 거리
return distance
h,w=map(int,input().split())
distance=[]
map=[]
for i in range(h):
map.append(list(input()))
for i in range(h):
for j in range(w):
# 시작점이 (i,j)일 때
if map[i][j]=='L':
distance.append(bfs(map,i,j,h,w))
print(max(distance))
from collections import deque
#상하좌우
dx=[0,0,1,-1]
dy=[1,-1,0,0]
M,N=map(int,input().split())
# 익은 토마토
queue=deque()
def bfs(tomato):
#토마토 익는데 걸리는 시간
date=0
while queue:
x,y,day=queue.popleft()
#상하좌우 토마토만
for pos in range(4):
nx=x+dx[pos]
ny=y+dy[pos]
if nx>=N or nx<0 or ny>=M or ny<0:
continue
#안 익은 토마토
if tomato[nx][ny]==0:
#익음
tomato[nx][ny]=1
#익은 토마토와 걸린 시간
queue.append((nx,ny,day+1))
date=day+1
return date
tomato=[]
#입력
for i in range(N):
tomato.append(list(map(int,input().split())))
for i in range(N):
for j in range(M):
#익은 토마토부터 시작하니까
if tomato[i][j]==1:
queue.append((i,j,0))
ans=bfs(tomato)
#안 익은 토마토가 있으면 실패(-1)
for i in range(N):
for j in range(M):
if tomato[i][j]==0:
ans=-1
break
print(ans)
대표적인 백트래킹 문제(백트래킹?)
퀸 N개를 서로 공격할 수 없게 놓는 문제
-> 퀸이 있는 방향의 상하좌우 대각선에는 또 다른 퀸이 없어야함.
N=int(input())
cnt=0
def dfs(queenPos,curCol):
global cnt
#같은 col에 있으면 안됨
if curCol in queenPos:
return
#지금 확인하고 있는 row
curRow=len(queenPos)
#대각선에 있는지 확인
for row,col in enumerate(queenPos):
#대각선에 있는지 확인
if abs(row-curRow)==abs(col-curCol):
return
#대각선에 없으면
queenPos.append(curCol)
#퀸을 다 자리에 놓았으면 방법+1
if len(queenPos)==N:
cnt+=1
#다음 퀸 자리에 앉히기
for col in range(N):
dfs(queenPos[:],col)
#맨 처음 퀸의 위치
for start in range(N):
queenPos=[] # idx=row, value=column
dfs(queenPos,start)
print(cnt)
PyPy3로만 돌아감
전역변수 안쓰고 싶은데
안쓰려면
cnt=0을 cnt=[0]으로 바꾸고 cnt+=1을 cnt[0]+=1로 바꾼 다음에 cnt[0]을 출력하면 됨
전역변수,배열