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