import sys
from collections import deque
def input():
return sys.stdin.readline().rstrip()
def island_bfs(x,y):
queue = deque()
queue.append((x,y))
visited[x][y] = True
island_check[x][y] = island_cnt
temp = [(x,y)]
while queue:
x,y = queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<N and 0<=ny<N:
if not visited[nx][ny] and arr[nx][ny]:
visited[nx][ny] = True
island_check[nx][ny] = island_cnt
queue.append((nx,ny))
temp.append((nx,ny))
island_list.append(temp)
N = int(input())
arr = [list(map(int,input().split())) for _ in range(N)]
visited = [[False for _ in range(N)] for _ in range(N)]
island_list = []
island_check = [[0 for _ in range(N)] for _ in range(N)]
island_cnt = 1
dx = [-1,0,1,0]
dy = [0,-1,0,1]
for x in range(N):
for y in range(N):
if arr[x][y] and not visited[x][y]:
island_bfs(x,y)
island_cnt += 1
result = float('inf')
for island_num in range(len(island_list)):
queue = deque(island_list[island_num])
visited = [[0 for _ in range(N)] for _ in range(N)]
dis = 1
while queue:
q_size = len(queue)
flag = False
for _ in range(q_size):
x,y = queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<N and 0<=ny<N:
if island_check[nx][ny] != island_num+1 and not visited[nx][ny]:
visited[nx][ny] = dis
queue.append((nx,ny))
if island_check[nx][ny]:
result = min(result,dis-1)
flag = True
break
if flag:
break
if flag:
break
dis += 1
print(result)

가장 첫 풀이는 직관적으로 푼 방식으로 각 섬들을 번호를 마킹해주고, 

 

한 섬의 있는 위치에서 다른 섬에 도착하는 최단 거리를 구해주는 방식이다.

 

 

import sys
from collections import deque
def input():
return sys.stdin.readline().rstrip()
def island_bfs(x,y):
queue = deque()
queue.append((x,y))
visited[x][y] = True
island_check[x][y] = island_cnt
temp = [(x,y)]
while queue:
x,y = queue.popleft()
bridge_queue.append((x,y,island_cnt,0))
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<N and 0<=ny<N:
if not visited[nx][ny] and arr[nx][ny]:
visited[nx][ny] = True
island_check[nx][ny] = island_cnt
queue.append((nx,ny))
temp.append((nx,ny))
island_list.append(temp)
def bfs():
global result
while bridge_queue:
x,y,island_num,dis = bridge_queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0<=nx<N and 0<=ny<N:
if island_check[nx][ny] == island_num:
continue
if result <= distance_list[nx][ny]:
return
if not distance_list[nx][ny]:
distance_list[nx][ny] = dis + 1
island_check[nx][ny] = island_num
bridge_queue.append((nx,ny,island_num,dis+1))
else:
if result > distance_list[nx][ny] + distance_list[x][y]:
result = distance_list[nx][ny] + distance_list[x][y]
N = int(input())
arr = [list(map(int,input().split())) for _ in range(N)]
visited = [[False for _ in range(N)] for _ in range(N)]
island_list = []
island_check = [[0 for _ in range(N)] for _ in range(N)]
island_cnt = 1
dx = [-1,0,1,0]
dy = [0,-1,0,1]
bridge_queue = deque()
for x in range(N):
for y in range(N):
if arr[x][y] and not visited[x][y]:
island_bfs(x,y)
island_cnt += 1
result = float('inf')
distance_list = [[0 for _ in range(N)] for _ in range(N)]
bfs()
print(result)

이 방식은 좀 더 빨리 풀 수 잇는 방식으로 위에서는 1섬마다 전부 초기화를 하고, 매번 구하는것에 반해

 

이 방식은 모든 섬에서 bfs를 동시에 시작하는 것이다.

 

만약 초기 상태의 점을 방문하게 되면, 해당 위치까지의 거리를 distance_list에 넣어주고, island_check에 해당 위치가 어느 섬에서 왔는지 마킹을 해준다.

 

그리고 만약 초기화 된 값이 아닌 이미 있는 값이라면, 비교를 해서 현재 위치의 distance_list[x][y] 와 distance_list[nx][ny]를 더한 값이 더 작으면 갱신을 해준다.

 

그리고 result가 distance_list[nx][ny]보다 작을 시에는 더 갱신할 경우의 수가 없으므로 함수를 종료해준다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 23289 온풍기 안녕!  (0) 2021.10.25
[BOJ/백준] 1958 LCS 3  (0) 2021.09.28
[BOJ/백준] 1943 동전 분배  (0) 2021.09.03
[BOJ/백준] 2143 두 배열의 합  (0) 2021.09.03
[BOJ/백준] 1823 수확  (0) 2021.09.03
import sys
from collections import defaultdict
def input():
return sys.stdin.readline().rstrip()
max_coins = 50000
for _ in range(3):
N = int(input())
coins = defaultdict(int)
dp = [0 for _ in range(max_coins+1)]
dp[0] = 1
total_sum = 0
for _ in range(N):
coin,cnts = map(int,input().split())
for cur_coin in range(max_coins,coin-1,-1):
if dp[cur_coin - coin]:
for cnt in range(cnts):
next_coin = cur_coin + coin * cnt
if 0<=next_coin<=max_coins:
dp[next_coin] = 1
total_sum += coin*cnts
if total_sum%2 or not dp[total_sum//2]:
print(0)
else:
print(1)

이 문제를 풀때 어려움을 많이 겪었다.

 

이 문제를 처음 푼 방식은 다음과 같다. dp는 동전을 만들수 있는 경우의 수이다.

 

먼저 dp[0]은 1로 초기화 해준다.

 

그리고 각 입력이 들어올때마다 dp를 max_coin에서 현재 들어온 동전인 coin 까지 반복문을 돌면서

 

cur_con - coin의 위치에 dp의 값이 존재하면, 만들 수 있는 경우의 수가 있으므로,

 

여기서 부터 다시 동전의 개수만큼 더해주면서 dp를 채워주면 된다.

 

이렇게 dp를 채워준 뒤에 전체 동전을 total_sum에 더해준다.

 

이렇게 한뒤에 만약 홀수 이거나 dp[total_sum//2]의 값이 존재하지 않으면 0을 출력한다.

 

 

import sys
from collections import defaultdict
def input():
return sys.stdin.readline().rstrip()
def solution():
N = int(input())
coins = []
total_coins = 0
for _ in range(N):
a,b = map(int,input().split())
coins.append((a,b))
total_coins += a*b
if total_coins%2:
return 0
else:
find_coin = total_coins//2
dp = [0 for _ in range(find_coin+1)]
dp[0] = 1
coins.sort(key= lambda x : -x[1])
acc_coins = 0
for coin,cnts in coins:
max_coin = coin*cnts
for i in range(min(max(acc_coins,max_coin),find_coin),coin-1,-1):
if dp[i-coin]:
for cnt in range(cnts):
next_coin = coin*cnt + i
if 0<=next_coin<=find_coin:
dp[next_coin] = 1
if dp[find_coin]:
return 1
acc_coins += max_coin
return 0
for _ in range(3):
print(solution())

 

 

이 풀이는 좀 더 빠르대신 좀 더 복잡하다. 위에서는 고정된 최대값 50000에서부터 하나하나씩 찾는거라 하면,

 

이 풀이는 이 코인에서 가능한 최대값에서부터 하나씩 내려가는 것이다.

 

탐색이 가능한 최대 범위는 acc_coins 누적된 값 아니면 max_coin 중 더 큰 값에서부터 하나씩 내려가야한다.

 

우리는 dp[i - coin] coin 단 1개를 빼서 존재했을때부터 해당 동전이 가지는 개수를 갱신해주기 때문이다.

 

여기서 또 주의해야할 점은 위의 최대값이 find_coin을 넘어갈순 없다. 그러므로 둘중 min값 부터 시작해주면 된다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1958 LCS 3  (0) 2021.09.28
[BOJ/백준] 2146 다리 만들기  (0) 2021.09.03
[BOJ/백준] 2143 두 배열의 합  (0) 2021.09.03
[BOJ/백준] 1823 수확  (0) 2021.09.03
[BOJ/백준] 1727 커플 만들기  (0) 2021.09.03
import sys
from collections import defaultdict
def input():
return sys.stdin.readline().rstrip()
T = int(input())
N = int(input())
A_arr = [0] + list(map(int,input().split()))
M = int(input())
B_arr = [0] +list(map(int,input().split()))
for i in range(N):
A_arr[i+1] += A_arr[i]
for j in range(M):
B_arr[j+1] += B_arr[j]
A_nums = defaultdict(int)
B_nums = defaultdict(int)
for i in range(1,N+1):
for j in range(i):
A_nums[A_arr[i] - A_arr[j]] += 1
for i in range(1,M+1):
for j in range(i):
B_nums[B_arr[i] - B_arr[j]] += 1
result = 0
for num in A_nums:
find_num = T -num
if B_nums.get(find_num):
result = result + A_nums[num] * B_nums[find_num]
print(result)

 

이 문제는 누적합을 이용해 풀었다. 이 문제는 다음과 같다. 두 배열이 주어지고,

 

두 배열의 원소들을 더해서 T가 나올 수 있는 경우의 수를 구하는 문제이다.

 

그래서 먼저 사전 작업을 해주었다.

 

각 배열들을 전부 누적합을 통해 특정 구간의 전체 합을 구하기 쉽게 만들어줬다.

 

이렇게 누적합을 미리 준비해주고,

 

j ->i 까지의 나올수 있는 모든 종류의 부분 합을 dict 에 저장을 해준다.

 

이렇게 사전 준비 작업을 했으면,

 

A_nums 라는 A 배열에서 나올 수 있는 모든 부분 배열의 합의 종류들의 key 값으로 탐색을 해준다.

 

T 에서 A에서 나올 수 있는 배열의 합을 뺀 값이 B에 존재 하면,

 

이 두 배열의 값들로 만들 수 있는 경우의 수는 A_nums[num] * B_nums[find_num]이 된다.

 

이 값들을 구해서 결과 값을 출력해주면 된다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 2146 다리 만들기  (0) 2021.09.03
[BOJ/백준] 1943 동전 분배  (0) 2021.09.03
[BOJ/백준] 1823 수확  (0) 2021.09.03
[BOJ/백준] 1727 커플 만들기  (0) 2021.09.03
[BOJ/백준] 1507 궁금한 민호  (0) 2021.09.03
import sys
sys.setrecursionlimit(20000)
def dfs(left_idx,right_idx,day):
if left_idx > right_idx:
return 0
if dp[left_idx][right_idx] != -1:
return dp[left_idx][right_idx]
dp[left_idx][right_idx] = max(dp[left_idx][right_idx], dfs(left_idx+1,right_idx,day+1) + v[left_idx]*day , dfs(left_idx,right_idx-1,day+1) + v[right_idx]*day)
return dp[left_idx][right_idx]
def input():
return sys.stdin.readline().rstrip()
N = int(input())
v = [int(input()) for _ in range(N)]
dp = [[-1 for _ in range(N)] for _ in range(N)]
print(dfs(0,N-1,1))

처음 풀었던 방식은 재귀를 이용해서 풀었다. 재귀는 다음과 같다.

left_idx는 현재 왼쪽 논 밭의 위치 right_idx는 오른쪽 논 밭의 위치를 나타낸다. 그리고 day는 현재의 날짜를 나타낸다.

left_idx> right_idx를 넘어가면 0을 return 해준다.

그리고 dp에서 초기값이 아니면 저장된 값을 해준다.

우리는 생각해보면 둘 중 하나를 선택해야한다. 여기서 왼쪽을 먼저 벨지 오른쪽을 먼저 벨지이다.

이 두가지 경우에 대해 재귀를 돌리고 그 결과 중 max값을 현재의 dp에 저장해주면 된다.

 dp[left_idx][right_idx] = max(dp[left_idx][right_idx], dfs(left_idx+1,right_idx,day+1) + v[left_idx]*day , dfs(left_idx,right_idx-1,day+1) + v[right_idx]*day)

현재 저장된 값과 왼쪽을 먼저 갔을때 오른쪽을 먼저깟을때를 구분해서 재귀를 돌려주면 된다.

import sys
def input():
return sys.stdin.readline().rstrip()
N = int(input())
v = [0]+[int(input()) for _ in range(N)]
dp = [[v[i] *N if i == j else 0 for i in range(N+1)] for j in range(N+1)]
for y in range(1,N+1):
for x in range(y-1,0,-1):
dp[x][y] = max(dp[x+1][y] + v[x] * (N - y + x), dp[x][y-1] + v[y]*(N-y+x))
print(dp[1][N])

두번쨰는 재귀 대신 반복문을 이용해서 푸는 방식이다.

여기서 dp 테이블의 뜻은 x에서 y까지 베었을때의 최대값이다.

먼저 dp를 초기화 시켜줘야한다. 초기화 시켜줄때 i와 j 가 같을때에는 v[i] * N을 해준다.

그 이유는 i번째에서 j번째까지 같을 때 최대값이 되는 경우는 가장 마지막 날에 이 벼를 베는 것이다.

그러므로 이 값으로 초기화를 해준다.

첫번째 풀이는 바깥에서 안쪽으로 베어나가는 느낌으로 풀었다면, 이 풀이는 안쪽에서 바깥쪽으로 베어나가는 느낌으로 푸는 방식이다.

x ->y까지 베었을때의 최대값이 나올 수 있는 경우의 수는

x+1~y를 남겨두고 x를 베었을 때

아니면 x~y-1 를 남겨두고 y를 베었을 때 이다.

그러면 우리는 dp[x+1][y] + v[x] * (N - y + x) 와 dp[x][y-1] + v[y] * (N -y +x)를 비교를 해서 최대값을 저장해주면 된다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1943 동전 분배  (0) 2021.09.03
[BOJ/백준] 2143 두 배열의 합  (0) 2021.09.03
[BOJ/백준] 1727 커플 만들기  (0) 2021.09.03
[BOJ/백준] 1507 궁금한 민호  (0) 2021.09.03
[BOJ/백준] 2026 소풍  (0) 2021.09.03
import sys
def input():
return sys.stdin.readline().rstrip()
N,M = map(int,input().split())
MA = [0]+list(map(int,input().split()))
WA = [0]+list(map(int,input().split()))
MA.sort()
WA.sort()
dp = [[0 for _ in range(M+1)] for _ in range(N+1)]
for x in range(1,N+1):
for y in range(1,M+1):
if x == y:
dp[x][y] = dp[x-1][y-1] + abs(MA[x]-WA[y])
elif x>y:
dp[x][y] = min(dp[x-1][y-1] + abs(MA[x]-WA[y]), dp[x-1][y])
else:
dp[x][y] = min(dp[x-1][y-1] + abs(MA[x]-WA[y]), dp[x][y-1])
print(dp[N][M])

이 문제는 성격의 차이의 합이 최소가 되도록 커플을 하는 것이다.

 

이 문제를 푸는 방식은 다음과 같다.

 

2차원 DP를 설정하고,  행은 남자 열은 여자를 뜻하는 것으로 하고,

 

x,y 까지 커플을 했을때, 최소 성격차를 저장했다고 하자.

 

이 문제는 사실 boj.kr/13398 하고 비슷하다고 생각한다.

 

만약 x == y가 같다면, 전부 커플이 되어야하기 때문에

dp[x][y] = dp[x-1][y-1] + abs(MA[x] - WA[y]) 가 되어야한다.

 

만약 x> y이면 우리는 남자는 커플이 될수도, 커플이 안될수 도 있다. 그러면 우리는 이중 최소값을 구해야한다.

 

이 남자가 커플이 된다하면. 위와 동일하게 dp[x-1][y-1] + abs(MA[x] -WA[y])와 동일하다.

 

이 남자가 커플로 선택되지 않으면, 이 남자의 성격은 그대로 버려지고, 이 남자가 솔로가 됬으므로, dp[x-1][y]와 동일하다.

 

이 2개의 값을 비교해서 최소값을 dp[x][y]에 넣어주면 된다.

 

x<y 일때는 여자가 더 많은 것이므로 위와 동일하게 하지만 x,y 만 바꿔주면 된다.

 

그리고 결과 적으로 dp[N][M}을 출력 해주면 된다.

 

여기서 좀 더 쉽게 풀기 위해서 남자 성격과 여자 성격의 list를 앞에 [0]을 넣어줘서 index를 편하게 해주었다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 2143 두 배열의 합  (0) 2021.09.03
[BOJ/백준] 1823 수확  (0) 2021.09.03
[BOJ/백준] 1507 궁금한 민호  (0) 2021.09.03
[BOJ/백준] 2026 소풍  (0) 2021.09.03
[BOJ/백준] 19535 ㄷㄷㄷㅈ  (0) 2021.09.03
import sys
def input():
return sys.stdin.readline().rstrip()
def floyd():
result = 0
for mid in range(N):
for start in range(N):
for end in range(N):
if start == end or end == mid or mid == start or start>end:continue
if arr[start][end] == arr[start][mid] + arr[mid][end]:
if (start,end) in edge_list:
edge_list.remove((start,end))
if arr[start][end] > arr[start][mid] + arr[mid][end]:
return -1
for x,y in edge_list:
result += arr[x][y]
return result
N = int(input())
arr = [list(map(int,input().split())) for _ in range(N)]
edge_list = set()
for i in range(N):
for j in range(N):
if i ==j or i>j: continue
edge_list.add((i,j))
print(floyd())

이 문제는 이해하기 어려웠던 문제였다.

 

이 문제를 읽어 보면 강호는 모든 쌍의 도시에 대해서 최소 이동시간을 구해놓았다고 했다.

 

그리고 민호는 이 표를 보고 원래 도로가 몇개 있는지를 구해보려고 한다고 적혀있다.

 

그러면 예제에 있는 도시 1-2, 2-3, 1-4, 3-4, 4-5, 3-5를 연결하는 도로만 있다고 가정해도,

 

강호가 구한 모든 쌍의 최솟값을 구할수 있다고 했다.

 

이 부분을 통해 유추를 해야한다.

 

원래는 여러 도로가 있었겠지만, 강호는 모든 쌍의 도시에 대해서 최소 이동시간을 구했기 때문에,

 

불 필요한 다른 도로들을 없애버린것이다.

 

즉 1->3 까지의 시간이 15인데 이것은 1->2 와 2->3을 더한 값과 동일하다.

 

1->5 또한 1->4 4->5를 더한 값과 동일하다.

 

즉 A라는 도시에서 B라는 도시를 갈때 A->C + C->B를 만족하는 경우가 있으면, A->B의 도로는 없어도, 동일한 시간 내에 갈 수 있으므로,

 

도로의 개수를 최솟값을 구할때 제외해도 된다.

 

이 부분을 주의해서 문제를 풀어주면 된다.

 

먼저 모든 도로들을 넣어주어야하는데, A->B와 B->A는 동일 하므로,

 

A<B를 만족하는 도로들을 먼저 edge_list에 전부 넣어준다.

 

그러면서 플로이드 와샬을 하면서

 

arr[start][end] == arr[start][mid] + arr[mid][end] 를 만족하는 경우엔, edge_list에서 그 도로를 제외 해준다.

 

또한 우리는 A<B인 경우만 하도록 했으므로, start> end 이거나, start or end 가 mid와 동일할때는 제외하고 검사해준다.

 

그리고 여기서 또 구해야하는 또 다른 경우는 불가능한 경우에 -1을 출력하는 조건이 있다.

 

이 조건을 만족하는 경우는 도시에서 다른 도시까지 가는 시간의 최소값이 갱신 되는 경우이다.

 

갱신 되었을 때에는 -1을 반환해주고, 아닌 경우에는 남은 edge_list를 통해 모든 도로의 시간의 합을 구하면 된다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1823 수확  (0) 2021.09.03
[BOJ/백준] 1727 커플 만들기  (0) 2021.09.03
[BOJ/백준] 2026 소풍  (0) 2021.09.03
[BOJ/백준] 19535 ㄷㄷㄷㅈ  (0) 2021.09.03
[BOJ/백준] 18513 쉼터  (0) 2021.09.03
import sys
sys.setrecursionlimit(10000)
def input():
return sys.stdin.readline().rstrip()
def checkFreinds(target_node,friend):
for node in friend:
if not friendly[node][target_node]:
return False
return True
def dfs(node,friend):
global K,result
if len(friend) == K:
result = list(map(str,friend))
sys.stdout.write('\n'.join(result))
exit(0)
return
for next_node in range(node+1,N+1):
if friend_cnt[next_node] < K-1:
continue
if visited[next_node]:
continue
if not friendly[node][next_node]:
continue
if not checkFreinds(next_node,friend):
continue
visited[next_node] = True
dfs(next_node,friend +[next_node])
visited[next_node] = False
K,N,F = map(int,input().split())
friendly = [[False for _ in range(N+1)] for _ in range(N+1)]
friend_cnt = [0 for _ in range(N+1)]
for _ in range(F):
x,y = map(int,input().split())
friendly[x][y] = True
friendly[y][x] = True
friend_cnt[x] += 1
friend_cnt[y] += 1
result = []
visited = [False for _ in range(N+1)]
for num in range(1,N+1):
if friend_cnt[num] < K-1:
continue
visited[num] = True
dfs(num,[num])
visited[num] = False
print(-1)

 이 문제는 N명 중 K명의 소풍을 보내는 것이다. 

 

단 조건이 모두가 서로 친구여야한다는 것이다.

 

그래서  N*N 친구의 관계를 나타내는 freiendly라는 행렬을 만들어 두었다.

 

서로 간에 친구관계이면 True 아니면 False가 되도록 했다.

 

이렇게 사전 준비 작업을 했다면, 백트래킹으로 문제를 접근하면 된다.

 

이 문제의 출력 조건은 만족하는 K명의 소풍을 갈수 있는 조합이 많으면 사전순으로 출력하는 것이다.

 

그러면 우리는 1번 학생부터 순차적으로 접근을 해서 만족을 하는 첫번째 K명의 조합이 사전 순으로 가장 빠른다는 것을 알 수 있게 된다.

 

여기서 재귀로 할때 주의를 해야할 것이 몇가지가 있다.

 

먼저. 현재 방문하는 친구의 친구 숫자가 K-1보다 작으면 자기를 포함해서 세도 K명이 안되기에 pass를 해주어야한다.

 

그리고, 문제의 조건 중에 소풍을 가는 친구들은 모두 친구관계 이어야한다.

 

그러므로, checkFriends 라는 함수를 통해 지금까지 뽑은 friend와 새로 방문한 next_node와 친구관계인지 파악을 해준다.

 

단 하나라도 만족하지 않으면 False를 반환해주면 된다.

 

그 뒤에는 DFS 처럼 백트래킹을 해주면 된다.

 

그리고, K를 만족하는 friend 조합이 나오면 exit로 파일을 종료하게 해준다.

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1727 커플 만들기  (0) 2021.09.03
[BOJ/백준] 1507 궁금한 민호  (0) 2021.09.03
[BOJ/백준] 19535 ㄷㄷㄷㅈ  (0) 2021.09.03
[BOJ/백준] 18513 쉼터  (0) 2021.09.03
[BOJ/백준] 17143 낚시왕  (0) 2021.09.03
import sys
from itertools import combinations
import math
def input():
return sys.stdin.readline().rstrip()
N = int(input())
graph = [[] for _ in range(N+1)]
for _ in range(N-1):
x,y = map(int,input().split())
graph[x].append(y)
graph[y].append(x)
d_cnt = 0
g_cnt = 0
for i in range(1,N+1):
if len(graph[i])>=3:
k = len(graph[i])
cnt = math.factorial(k)/(math.factorial(3)*math.factorial(k-3))
g_cnt += cnt
if len(graph[i])>=2:
for next_node in graph[i]:
if len(graph[next_node])>=2:
a = len(graph[i]) - 1
b = len(graph[next_node]) - 1
d_cnt += (a*b)
d_cnt//=2
if d_cnt > g_cnt*3:
print('D')
elif d_cnt < g_cnt*3:
print('G')
else:
print('DUDUDUNGA')

ㅈ 을 그리는 방법은 해당 노드를 기준으로 자식노드가 3개이상이면 구할수 있따. 그러므로 자식노드 중 3개를 고르는 경우의 수를 더해주면 된다.

 

 

ㄷ을 그리는 방법은 다음과 같다. 서로 연결된 두 노드의 자식노드가 2개이상이어야할때이다.

 

왜냐하면 서로 연결이 되어 있으므로, 하나는 빼고 서로 다른 노드들의 개수를 곱해주면 된다.

 

 

import sys
def input():
return sys.stdin.readline().rstrip()
def nC3(n):
return (n*(n-1)*(n-2))//6
N = int(input())
graph_node_cnt = [0 for _ in range(N+1)]
edge_list = []
for _ in range(N-1):
x,y = map(int,input().split())
graph_node_cnt[x] += 1
graph_node_cnt[y] += 1
edge_list.append((x,y))
g_cnt = 0
d_cnt = 0
for node in range(1,N+1):
if graph_node_cnt[node] >=3:
g_cnt += nC3(graph_node_cnt[node])
for x,y in edge_list:
if graph_node_cnt[x]>=2 and graph_node_cnt[y]>=2:
d_cnt += (graph_node_cnt[x]-1)*(graph_node_cnt[y]-1)
if d_cnt>3*g_cnt:
print('D')
elif d_cnt < 3*g_cnt:
print('G')
else:
print('DUDUDUNGA')

이건 팩토리얼 대신 사용한 것이다.

 

 

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ/백준] 1507 궁금한 민호  (0) 2021.09.03
[BOJ/백준] 2026 소풍  (0) 2021.09.03
[BOJ/백준] 18513 쉼터  (0) 2021.09.03
[BOJ/백준] 17143 낚시왕  (0) 2021.09.03
[BOJ/백준] 17090 미로 탈출하기  (0) 2021.09.03

+ Recent posts