728x90
반응형

문제:

민식이는 수학학원에서 단어 수학 문제를 푸는 숙제를 받았다.

단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.

예를 들어, GCF + ACDEB를 계산한다고 할 때, A = 9, B = 4, C = 8, D = 6, E = 5, F = 3, G = 7로 결정한다면, 두 수의 합은 99437이 되어서 최대가 될 것이다.

N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.

입력:

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대 10개이고, 수의 최대 길이는 8이다. 서로 다른 문자는 서로 다른 숫자를 나타낸다.

출력:

첫째 줄에 주어진 단어의 합의 최댓값을 출력한다.

풀이방법:

 모든 케이스에 대해 수행하기에는 경우의 수가 너무 많기 때문에 그리디하게 이 문제를 해결하도록 한다. 각 알파벳에 대해 가중치를 구한 뒤에 가중치가 높은 순서대로 9부터 숫자를 할당하면 된다.

 가중치는 알파벳이 있는 위치, 갯수에 따라 다르게 설정한다. ABC와 같이 있을 때, 이를 숫자로 보면 A00, B0, C와 같다. 즉 자릿수가 클수록 더 높은 가중치를 가지게 된다. 따라서 word를 순회하면서 가중치를 순회하도록 한다. 이를 dict 형태로 저장하는데, 불필요한 키들을 줄이기 위해 defaultdict을 사용하여 깔끔하게 정리하도록 한다.

 최종적으로는 가중치에 따라 값을 부여하고 합을 누적시키도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from collections import defaultdict
 
def word2number(word):
    for i in range(len(word)):
        alpha[word[i]] += pow(10,len(word)-i-1)
        
= int(input())
alpha = defaultdict(int)
for _ in range(N):
    word = input()
    word2number(word)
 
imp_list = sorted(alpha.items(),key = lambda x: -x[1])
answer = 0
number = 9
for imp in imp_list:
    answer+=imp[1]*number
    number-=1
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/1339

 

1339번: 단어 수학

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 15988. 1, 2, 3 더하기  (0) 2021.10.25
[BOJ] 13023. ABCDE  (0) 2021.10.22
[BOJ] 15658. 연산자 끼워넣기 (2)  (0) 2021.10.20
[BOJ] 17140. 이차원 배열과 연산  (0) 2021.10.19
[BOJ]2659. 십자카드 문제  (0) 2021.10.18
728x90
반응형

문제:

N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다. 연산자의 개수는 N-1보다 많을 수도 있다. 모든 수의 사이에는 연산자를 한 개 끼워넣어야 하며, 주어진 연산자를 모두 사용하지 않고 모든 수의 사이에 연산자를 끼워넣을 수도 있다.

우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다.

예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 3개, 뺄셈(-) 2개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 250가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.

  • 1+2+3-4×5÷6
  • 1÷2+3+4-5×6
  • 1+2÷3×4-5+6
  • 1÷2×3-4+5+6
  • 1+2+3+4-5-6
  • 1+2+3-4-5×6

식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.

  • 1+2+3-4×5÷6 = 1
  • 1÷2+3+4-5×6 = 12
  • 1+2÷3×4-5+6 = 5
  • 1÷2×3-4+5+6 = 7
  • 1+2+3+4-5-6 = -1
  • 1+2+3-4-5×6 = -18

N개의 수와 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1보다 크거나 같고, 4N보다 작거나 같은 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다. 

출력:

첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다. 연산자를 어떻게 끼워넣어도 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력만 주어진다. 또한, 앞에서부터 계산했을 때, 중간에 계산되는 식의 결과도 항상 -10억보다 크거나 같고, 10억보다 작거나 같다.

풀이방법:

 처음에는 이 문제를 permutation을 사용해서 풀려고 했으나 시간초과나 메모리초과가 발생하게 되었다. 따라서 조금 더 효율적인 방법을 찾고자 고안한 방법은 백트래킹 방법이다.

 permutation은 매 candidate마다 값을 계산해야 한다. 하지만 1,1,3이라는 숫자가 있을 때, 1+1을 한번만 구한 뒤에 3에다가 추가적인 연산을 하는 것이 더 효율적이다. 따라서 dfs를 사용해서 백트래킹 방법을 사용하여 모든 케이스에 대해 연산을 수행하도록 한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
= int(input())
numbers = list(map(int,input().split()))
counts = list(map(int,input().split()))
max_answer = -float('inf')
min_answer = float('inf')
 
def dfs(num_idx, value):
    global max_answer, min_answer
    if num_idx == N:
        max_answer = max(max_answer, value)
        min_answer = min(min_answer, value)
        return
    if counts[0> 0:
        counts[0-= 1
        dfs(num_idx+1, value+numbers[num_idx])
        counts[0+= 1
    if counts[1> 0:
        counts[1-= 1
        dfs(num_idx+1, value-numbers[num_idx])
        counts[1+= 1
    if counts[2> 0:
        counts[2-= 1
        dfs(num_idx+1, value*numbers[num_idx])
        counts[2+= 1
    if counts[3> 0:
        counts[3-= 1
        if value < 0:
            tmp = -(abs(value)//numbers[num_idx])
        else:
            tmp = value//numbers[num_idx]
        dfs(num_idx+1, tmp)
        counts[3+= 1
 
dfs(1,numbers[0])
print(max_answer)
print(min_answer)
cs

문제링크:

https://www.acmicpc.net/problem/15658

 

15658번: 연산자 끼워넣기 (2)

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1보다 크거나 같고, 4N보다 작거나 같은 4개의 정수가 주어지는데, 차례대

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 13023. ABCDE  (0) 2021.10.22
[BOJ]1339. 단어 수학  (0) 2021.10.21
[BOJ] 17140. 이차원 배열과 연산  (0) 2021.10.19
[BOJ]2659. 십자카드 문제  (0) 2021.10.18
[BOJ] 2668. 숫자고르기  (0) 2021.10.15
728x90
반응형

문제:

크기가 3×3인 배열 A가 있다. 배열의 인덱스는 1부터 시작한다. 1초가 지날때마다 배열에 연산이 적용된다.

  • R 연산: 배열 A의 모든 행에 대해서 정렬을 수행한다. 행의 개수 ≥ 열의 개수인 경우에 적용된다.
  • C 연산: 배열 A의 모든 열에 대해서 정렬을 수행한다. 행의 개수 < 열의 개수인 경우에 적용된다.

한 행 또는 열에 있는 수를 정렬하려면, 각각의 수가 몇 번 나왔는지 알아야 한다. 그 다음, 수의 등장 횟수가 커지는 순으로, 그러한 것이 여러가지면 수가 커지는 순으로 정렬한다. 그 다음에는 배열 A에 정렬된 결과를 다시 넣어야 한다. 정렬된 결과를 배열에 넣을 때는, 수와 등장 횟수를 모두 넣으며, 순서는 수가 먼저이다.

예를 들어, [3, 1, 1]에는 3이 1번, 1가 2번 등장한다. 따라서, 정렬된 결과는 [3, 1, 1, 2]가 된다. 다시 이 배열에는 3이 1번, 1이 2번, 2가 1번 등장한다. 다시 정렬하면 [2, 1, 3, 1, 1, 2]가 된다.

정렬된 결과를 배열에 다시 넣으면 행 또는 열의 크기가 달라질 수 있다. R 연산이 적용된 경우에는 가장 큰 행을 기준으로 모든 행의 크기가 변하고, C 연산이 적용된 경우에는 가장 큰 열을 기준으로 모든 열의 크기가 변한다. 행 또는 열의 크기가 커진 곳에는 0이 채워진다. 수를 정렬할 때 0은 무시해야 한다. 예를 들어, [3, 2, 0, 0]을 정렬한 결과는 [3, 2]를 정렬한 결과와 같다.

행 또는 열의 크기가 100을 넘어가는 경우에는 처음 100개를 제외한 나머지는 버린다.

배열 A에 들어있는 수와 r, c, k가 주어졌을 때, A[r][c]에 들어있는 값이 k가 되기 위한 최소 시간을 구해보자.

입력:

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100)

둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

출력:

A[r][c]에 들어있는 값이 k가 되기 위한 연산의 최소 시간을 출력한다. 100초가 지나도 A[r][c] = k가 되지 않으면 -1을 출력한다.

풀이방법:

 연산에 따라 행과 열에 각각 행동을 취해야 하는 문제다. 일반적으로 열에다가 특정 연산을 취하는 것은 어렵기 때문에 열에 있는 내용들을 50번줄과 같이 행으로 전환해서 수행하도록 한다.

 각 행을 dict을 사용해서 갯수를 count하고 (횟수, 숫자)를 기준으로 정렬하도록 한다. 각 행을 임시 배열에 저장한 뒤에 가장 긴 행을 기준으로 나머지 부분에 0을 채워넣도록 한다. 만약 열에 대해서 수행했다면 50번줄의 코드를 다시 실행하여 열로 바꿔주도록 한다. 이를 k를 찾거나 100초가 넘을때까지 계속 반복해서 수행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from collections import defaultdict
import copy
 
def make_new_A(A,max_idx):
    next_A = []
    for a in A:
        r = []
        for j in a:
            r.append(j[0])
            r.append(j[1])
        count = 0
        while 2*(max_idx-len(a))>count:
            r.append(0)
            count+=1
        next_A.append(r)
    return next_A
  
 
r,c,k = map(int,input().split())
 
= []
for _ in range(3):
    A.append(list(map(int,input().split())))
 
time = 0
while True:
    A_tmp = copy.deepcopy(A)
    if time>100:
        break
    try:
        if A_tmp[r-1][c-1]==k:
            break
    except:
        pass
    #R
    if len(A_tmp) >= len(A_tmp[0]):
        new_A = []
        max_row = 0
        for _, v in enumerate(A_tmp):
            tmp_dict = defaultdict(int)
            for i in v:
                if i:
                    tmp_dict[i]+=1
            row = sorted(tmp_dict.items(),key = lambda x : (x[1],x[0]))
            if len(row) > max_row:
                max_row = len(row)
            new_A.append(row)
        A = make_new_A(new_A,max_row)
    else:
        A_tmp = list(map(list,zip(*A_tmp)))
        new_A = []
        max_row = 0
        for _, v in enumerate(A_tmp):
            tmp_dict = defaultdict(int)
            for i in v:
                if i:
                    tmp_dict[i]+=1
            row = sorted(tmp_dict.items(),key = lambda x : (x[1],x[0]))
            if len(row) > max_row:
                max_row = len(row)
            new_A.append(row)
        A = make_new_A(new_A,max_row)
        A = list(map(list,zip(*A)))
    time+=1
if time>100:
    print(-1)
else:
    print(time)
cs

문제링크:

https://www.acmicpc.net/problem/17140

 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1339. 단어 수학  (0) 2021.10.21
[BOJ] 15658. 연산자 끼워넣기 (2)  (0) 2021.10.20
[BOJ]2659. 십자카드 문제  (0) 2021.10.18
[BOJ] 2668. 숫자고르기  (0) 2021.10.15
[BOJ] 16918. 봄버맨  (0) 2021.10.14
728x90
반응형

문제:

위와 같은 십자모양의 한 장의 카드에서, 네 모서리에 1 이상 9 이하의 숫자가 하나씩 씌여 있다. 이 네 개의 숫자 중에는 같은 숫자도 있을 수 있다.

모든 가능한 십자 카드가 주어질 때, 각각의 카드는 다음과 같은 '시계수'라는 번호를 가진다. 시계수는 카드의 숫자들을 시계 방향으로 읽어서 만들어지는 네 자리 수들 중에서 가장 작은 수이다. 위 그림의 카드는 시계방향으로 3227, 2273, 2732, 7322로 읽을 수 있으므로, 이 카드의 시계수는 가장 작은 수인 2273이다.

입력으로 주어진 카드의 시계수를 계산하여, 그 시계수가 모든 시계수들 중에서 몇 번째로 작은 시계수인지를 알아내는 프로그램을 작성하시오.

예를 들어서, 다음과 같은 십자 카드의 시계수는 1122이며, 이 시계수보다 작은 시계수들은 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119 뿐이므로 1122는 10번째로 작은 시계수다. (여기서 십자카드는 0 이 나타날 수 없으므로 1120은 시계수가 될 수 없다. 또한 1121 이 적혀있는 카드의 시계수는 1112이므로, 1121은 시계수가 될 수 없다.

입력:

입력은 한 줄로 이루어지며, 이 한 줄은 카드의 네 모서리에 씌여있는 1 이상 9 이하의 숫자 4개가 시계 방향으로 입력된다. 각 숫자 사이에는 빈칸이 하나 있다.

출력:

입력된 카드의 시계수가 모든 시계수들 중에서 몇 번째로 작은 시계수인지를 출력한다.

풀이방법:

 1111부터 시작해서 주어진 수의 시계수까지 하나씩 다 구하면서 몇 번째인지 출력하도록 한다.

우선 입력된 카드의 시계수를 구한 뒤에 1111부터 해당 시계수까지 while로 반복한다. 이 때, 1120, 1121와 같이 시계수가 아닌 경우도 있기 때문에 해당 경우는 조건문을 사용하여 제외하도록 한다. 또한 회전연산을 쉽게 하기 위해 collections에 있는 deque의 rotate를 사용했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from collections import deque
find_ = deque(map(int,input().split()))
 
def find_clock_num(number):
    find_ = deque(number)
    clock_number = 10000
    for _ in range(4):
        now = find_[0]*1000+find_[1]*100+find_[2]*10+find_[3]*1
        if now < clock_number:
            clock_number = now
        find_.rotate(1)
    return clock_number
 
clock_number = find_clock_num(find_)
    
answer = 0
start = 1111
while start<=clock_number:
    if find_clock_num(list(map(int,list(str(start))))) == start:
        answer+=1
    start+=1
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/2659

 

2659번: 십자카드 문제

입력은 한 줄로 이루어지며, 이 한 줄은 카드의 네 모서리에 씌여있는 1 이상 9 이하의 숫자 4개가 시계 방향으로 입력된다. 각 숫자 사이에는 빈칸이 하나 있다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 15658. 연산자 끼워넣기 (2)  (0) 2021.10.20
[BOJ] 17140. 이차원 배열과 연산  (0) 2021.10.19
[BOJ] 2668. 숫자고르기  (0) 2021.10.15
[BOJ] 16918. 봄버맨  (0) 2021.10.14
[BOJ] 16236. 아기 상어  (0) 2021.10.13
728x90
반응형

문제:

세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절히 뽑으면, 그 뽑힌 정수들이 이루는 집합과, 뽑힌 정수들의 바로 밑의 둘째 줄에 들어있는 정수들이 이루는 집합이 일치한다. 이러한 조건을 만족시키도록 정수들을 뽑되, 최대로 많이 뽑는 방법을 찾는 프로그램을 작성하시오. 예를 들어, N=7인 경우 아래와 같이 표가 주어졌다고 하자.

이 경우에는 첫째 줄에서 1, 3, 5를 뽑는 것이 답이다. 첫째 줄의 1, 3, 5밑에는 각각 3, 1, 5가 있으며 두 집합은 일치한다. 이때 집합의 크기는 3이다. 만약 첫째 줄에서 1과 3을 뽑으면, 이들 바로 밑에는 정수 3과 1이 있으므로 두 집합이 일치한다. 그러나, 이 경우에 뽑힌 정수의 개수는 최대가 아니므로 답이 될 수 없다.

입력:

첫째 줄에는 N(1≤N≤100)을 나타내는 정수 하나가 주어진다. 그 다음 줄부터는 표의 둘째 줄에 들어가는 정수들이 순서대로 한 줄에 하나씩 입력된다.

출력:

첫째 줄에 뽑힌 정수들의 개수를 출력하고, 그 다음 줄부터는 뽑힌 정수들을 작은 수부터 큰 수의 순서로 한 줄에 하나씩 출력한다.

풀이방법:

 뽑힌 정수들이 이루는 집학과 뽑힌 정수들의 바로 밑의 둘째 줄에 들어있는 정수들이 이루는 집합이 일치한다는 것은 그 해당 정수들로 사이클이 이뤄진다는 것과 동일하다. 즉, 이 문제는 숫자 배열들 중에서 가장 큰 사이클을 찾으면 된다.

 따라서 사이클을 찾기 위해 DFS를 사용하여 문제를 풀도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from collections import defaultdict
 
def dfs(now,start):
    visited[now] = 1
    
    for n in numbers[now]:
        if not visited[n]:
            dfs(n,start)
        elif visited[n] and n==start:
            answer.append(n)
 
= int(input())
numbers = defaultdict(list)
for i in range(1,N+1):
    numbers[i].append(int(input()))
    
answer = []
for i in range(1,N+1):
    visited = [0 for _ in range(N+1)]
    dfs(i,i)
    
print(len(answer))
for i in range(len(answer)):
    print(answer[i])  
cs

문제링크:

https://www.acmicpc.net/problem/2668

 

2668번: 숫자고르기

세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 17140. 이차원 배열과 연산  (0) 2021.10.19
[BOJ]2659. 십자카드 문제  (0) 2021.10.18
[BOJ] 16918. 봄버맨  (0) 2021.10.14
[BOJ] 16236. 아기 상어  (0) 2021.10.13
[BOJ] 15683. 감시  (0) 2021.10.12
728x90
반응형

문제:

봄버맨은 크기가 R×C인 직사각형 격자판 위에서 살고 있다. 격자의 각 칸은 비어있거나 폭탄이 들어있다.

폭탄이 있는 칸은 3초가 지난 후에 폭발하고, 폭탄이 폭발한 이후에는 폭탄이 있던 칸이 파괴되어 빈 칸이 되며, 인접한 네 칸도 함께 파괴된다. 즉, 폭탄이 있던 칸이 (i, j)인 경우에 (i+1, j), (i-1, j), (i, j+1), (i, j-1)도 함께 파괴된다. 만약, 폭탄이 폭발했을 때, 인접한 칸에 폭탄이 있는 경우에는 인접한 폭탄은 폭발 없이 파괴된다. 따라서, 연쇄 반응은 없다.

봄버맨은 폭탄에 면역력을 가지고 있어서, 격자판의 모든 칸을 자유롭게 이동할 수 있다. 봄버맨은 다음과 같이 행동한다.

  • 가장 처음에 봄버맨은 일부 칸에 폭탄을 설치해 놓는다. 모든 폭탄이 설치된 시간은 같다.
  • 다음 1초 동안 봄버맨은 아무것도 하지 않는다.
  • 다음 1초 동안 폭탄이 설치되어 있지 않은 모든 칸에 폭탄을 설치한다. 즉, 모든 칸은 폭탄을 가지고 있게 된다. 폭탄은 모두 동시에 설치했다고 가정한다.
  • 1초가 지난 후에 3초 전에 설치된 폭탄이 모두 폭발한다.
  • 3과 4를 반복한다.

폭탄을 설치해놓은 초기 상태가 주어졌을 때, N초가 흐른 후의 격자판 상태를 구하려고 한다.

예를 들어, 초기 상태가 아래와 같은 경우를 보자.

1초가 지난 후에는 아무 일도 벌어지지 않기 때문에, 위와 같다고 볼 수 있다. 1초가 더 흐른 후에 격자판의 상태는 아래와 같아진다.

1초가 지난 후엔 가운데에 있는 폭탄이 폭발해 가운데 칸과 인접한 네 칸이 빈 칸이 된다.

입력:

첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.

출력:

총 R개의 줄에 N초가 지난 후의 격자판 상태를 출력한다.

풀이방법:

 문제의 조건대로 폭탄을 설치하고 터트리는 과정을 반복하면 된다. 문제에서는 설치하는 과정, 폭발하는 과정이 1초씩 각각 수행되는 것으로 나타나지만 같은 while에서 수행하도록 한다.

 현재 지도에서 폭탄이 있는 위치를 찾아 좌표만을 저장한 후 빈 공간에 폭탄을 모두 채워 넣는다.( 따라서 매 짝수초마다 폭탄으로 가득찬 지도를 얻는다.) 그리고 폭탄을 설치하기 전에 찾았던 폭탄의 위치를 근거로만 폭탄을 제거하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
dx = [-1,0,1,0]
dy = [0,1,0,-1]
 
def del_bomb(maps):
    while bombs:
        x,y= bombs.popleft()
        maps[x][y] = '.'
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0<=nx<and 0<=ny<C:
                maps[nx][ny]='.'
def set_bomb(maps):
    for i in range(R):
        for j in range(C):
            if maps[i][j]=='.':
                maps[i][j] = 'O'
                
def find_bomb(maps):
    for i in range(R):
        for j in range(C):
            if maps[i][j]=='O':
                bombs.append((i,j))
 
from collections import deque
R, C, N = map(int,input().split())
maps = []
for _ in range(R):
    maps.append(list(input()))
    
time = 1
while time!=N:
    bombs = deque()
    find_bomb(maps)
    set_bomb(maps)
    time+=1
    if time==N:
        break
    del_bomb(maps)
    time+=1
        
 
for map_ in maps:
    print("".join(map_))
cs

문제링크:

https://www.acmicpc.net/problem/16918

 

16918번: 봄버맨

첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2659. 십자카드 문제  (0) 2021.10.18
[BOJ] 2668. 숫자고르기  (0) 2021.10.15
[BOJ] 16236. 아기 상어  (0) 2021.10.13
[BOJ] 15683. 감시  (0) 2021.10.12
[BOJ] 14500. 테트로미노  (0) 2021.10.08
728x90
반응형

문제:

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다.

아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다.

아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크기보다 작은 물고기만 먹을 수 있다. 따라서, 크기가 같은 물고기는 먹을 수 없지만, 그 물고기가 있는 칸은 지나갈 수 있다.

아기 상어가 어디로 이동할지 결정하는 방법은 아래와 같다.

  • 더 이상 먹을 수 있는 물고기가 공간에 없다면 아기 상어는 엄마 상어에게 도움을 요청한다.
  • 먹을 수 있는 물고기가 1마리라면, 그 물고기를 먹으러 간다.
  • 먹을 수 있는 물고기가 1마리보다 많다면, 거리가 가장 가까운 물고기를 먹으러 간다.
    • 거리는 아기 상어가 있는 칸에서 물고기가 있는 칸으로 이동할 때, 지나야하는 칸의 개수의 최솟값이다.
    • 거리가 가까운 물고기가 많다면, 가장 위에 있는 물고기, 그러한 물고기가 여러마리라면, 가장 왼쪽에 있는 물고기를 먹는다.

아기 상어의 이동은 1초 걸리고, 물고기를 먹는데 걸리는 시간은 없다고 가정한다. 즉, 아기 상어가 먹을 수 있는 물고기가 있는 칸으로 이동했다면, 이동과 동시에 물고기를 먹는다. 물고기를 먹으면, 그 칸은 빈 칸이 된다.

아기 상어는 자신의 크기와 같은 수의 물고기를 먹을 때 마다 크기가 1 증가한다. 예를 들어, 크기가 2인 아기 상어는 물고기를 2마리 먹으면 크기가 3이 된다.

공간의 상태가 주어졌을 때, 아기 상어가 몇 초 동안 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는지 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 공간의 크기 N(2 ≤ N ≤ 20)이 주어진다.

둘째 줄부터 N개의 줄에 공간의 상태가 주어진다. 공간의 상태는 0, 1, 2, 3, 4, 5, 6, 9로 이루어져 있고, 아래와 같은 의미를 가진다.

  • 0: 빈 칸
  • 1, 2, 3, 4, 5, 6: 칸에 있는 물고기의 크기
  • 9: 아기 상어의 위치

아기 상어는 공간에 한 마리 있다.

출력:

첫째 줄에 아기 상어가 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는 시간을 출력한다.

풀이방법:

 BFS를 통해 아기 상어가 먹을 수 있는 물고기를 찾은 후에 문제 조건에 맞게 정렬하여 하나씩 먹으면 된다.

무한 while을 사용하며 엄마 상어를 호출할 경우(탐색했지만 먹을 수 있는 물고기가 없는 경우)에만 빠져나올 수 있도록 한다. eat_fish함수를 통해 탐색하며 일반적인 bfs 알고리즘을 사용한다. 이 때, 빠른 탐색을 위해 좌표만을 저장하는 것이 아닌 distance도 구해서 먹을 수 있는 물고기를 찾는 조건을 한번의 sort로 찾을 수 있도록 한다.

 먹을 수 있는 물고기를 찾은 경우에는 maps를 최신화하고, 아기 상어의 size를 늘린다. 이 때, 아기 상어의 size가 커진 경우에는 count를 초기화 시키도록 한다. (2개 먹음 -> 성장 -> 다시 3개 먹음 -> 성장 -> ...)

 BFS 과정에서 찾은 distance를 시간에 더하도록 하며, 못 찾을 때 while을 나와 time을 출력한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
dx = [-1,0,1,0]
dy = [0,1,0,-1]
 
def eat_fish(maps,i,j):
    queue = [(i,j,0)]
    visited = [[0 for _ in range(N)] for _ in range(N)]
    visited[i][j] = 1
    fish = []
    while queue:
        next_ = []
        for q in queue:
            x,y,count = q
            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]:
                        if 0<= maps[nx][ny] <= size:
                            if maps[nx][ny]!=0 and maps[nx][ny] < size:
                                fish.append((nx,ny,count+1))
                            next_.append((nx,ny,count+1))
                            visited[nx][ny] = 1
        queue = next_
    if fish:
        fish.sort(key=lambda x: (x[2],x[0],x[1]))
        return fish[0][0], fish[0][1],fish[0][2]
    else:
        return -1,-1,-1
            
= int(input())
 
maps = []
for _ in range(N):
    maps.append(list(map(int,input().split())))
    
ate  = maps.copy()
eat_count = 0
total_count = 0
time = 0
for i in range(N):
    for j in range(N):
        if maps[i][j]==9:
            x,y = i,j
            ate[x][y] = 0
        elif maps[i][j]:
            total_count+=1
 
size = 2
while True:
    nx,ny,d = eat_fish(maps,x,y)
    if nx==-1 and ny==-1:
        break
    else:
        maps[nx][ny] = 0
        time+=d
        eat_count+=1
    if eat_count==size:
        size+=1
        eat_count = 0
    x,y = nx,ny
print(time)
cs

문제링크:

https://www.acmicpc.net/problem/16236

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 2668. 숫자고르기  (0) 2021.10.15
[BOJ] 16918. 봄버맨  (0) 2021.10.14
[BOJ] 15683. 감시  (0) 2021.10.12
[BOJ] 14500. 테트로미노  (0) 2021.10.08
[BOJ]2458. 키 순서  (0) 2021.10.07
728x90
반응형

문제:

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감시할 수 있는 방법은 다음과 같다.

1번 CCTV는 한 쪽 방향만 감시할 수 있다. 2번과 3번은 두 방향을 감시할 수 있는데, 2번은 감시하는 방향이 서로 반대방향이어야 하고, 3번은 직각 방향이어야 한다. 4번은 세 방향, 5번은 네 방향을 감시할 수 있다.

CCTV는 감시할 수 있는 방향에 있는 칸 전체를 감시할 수 있다. 사무실에는 벽이 있는데, CCTV는 벽을 통과할 수 없다. CCTV가 감시할 수 없는 영역은 사각지대라고 한다.

CCTV는 회전시킬 수 있는데, 회전은 항상 90도 방향으로 해야 하며, 감시하려고 하는 방향이 가로 또는 세로 방향이어야 한다.

지도에서 0은 빈 칸, 6은 벽, 1~5는 CCTV의 번호이다. 위의 예시에서 1번의 방향에 따라 감시할 수 있는 영역을 '#'로 나타내면 아래와 같다.

CCTV는 벽을 통과할 수 없기 때문에, 1번이 → 방향을 감시하고 있을 때는 6의 오른쪽에 있는 칸을 감시할 수 없다.

위의 예시에서 감시할 수 있는 방향을 알아보면 아래와 같다.

CCTV는 CCTV를 통과할 수 있다. 아래 예시를 보자.

위와 같은 경우에 2의 방향이 ↕ 3의 방향이 ←와 ↓인 경우 감시받는 영역은 다음과 같다.

사무실의 크기와 상태, 그리고 CCTV의 정보가 주어졌을 때, CCTV의 방향을 적절히 정해서, 사각 지대의 최소 크기를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 사무실의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 8)

둘째 줄부터 N개의 줄에는 사무실 각 칸의 정보가 주어진다. 0은 빈 칸, 6은 벽, 1~5는 CCTV를 나타내고, 문제에서 설명한 CCTV의 종류이다. 

CCTV의 최대 개수는 8개를 넘지 않는다.

출력:

첫째 줄에 사각 지대의 최소 크기를 출력한다.

풀이방법:

 CCTV 번호에 따라 감시할 수 있는 방향이 다르고, 같은 번호라도 회전이 가능하기 때문에 같은 번호도 서로 다른 방향을 가리킬 수 있다. 각 번호에 따라 나올 수 있는 경우의 수는 동,서,남,북 4가지 경우밖에 없다. 따라서 CCTV 번호에 따라 기준이 되는 축을 기준으로 동,서,남,북으로 각각 배정을 해보며 사각지대가 최소가 되는 경우를 찾도록 한다. 즉, 백트래킹을 사용해 모든 경우에 대해 계산한다고 생각하면 된다.

 cctv를 설정하기에 앞서서 지도 상의 cctv의 개수와 좌표를 먼저 배열에 담아둔다. 이 배열을 기준으로 모든 cctv가 배치되었는지 확인하기 때문이다. 이 작업을 모두 마친 뒤 cctv를 하나씩 배치하도록 한다. 방향에 따라, 번호에 따라 cctv를 설정하며, 매 cctv 설정마다 visited를 최신화하여 사각지대를 계산할 수 있도록 한다. 또한 같은 번호의 cctv를 추후 회전하는 것을 고려하기 위해 rollback이라는 배열에 cctv가 탐색할 수 있는 좌표들을 담아 다시 되돌릴 수 있도록 한다.

 cctv를 모두 설정할 때마다 사각지대의 수를 구하며, 그 중 가장 최소인 값을 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
dx = [-1010]
dy = [010-1]
 
def watch(idx):
    global answer
    if idx==cctv_count:
        tmp = 0
        for i in range(N):
            for j in range(M):
                if not visited[i][j] and not office[i][j]:
                    tmp+=1
        return tmp
    x,y = cctvs[idx]
    for i in range(4):
        del_dir = []
        if office[x][y]==1:
            del_dir.append(i)
        elif office[x][y]==2:
            del_dir.append(i)
            del_dir.append((i+2)%4)
        elif office[x][y]==3:
            del_dir.append(i)
            del_dir.append((i+1)%4)
        elif office[x][y]==4:
            del_dir.append(i)
            del_dir.append((i+1)%4)
            del_dir.append((i+2)%4)
        elif office[x][y]==5:
            del_dir.append(i)
            del_dir.append((i+1)%4)
            del_dir.append((i+2)%4)
            del_dir.append((i+3)%4)
            
        rollback = []
        for dd in del_dir:
            nx,ny = x,y
            while True:
                nx, ny = nx + dx[dd], ny+dy[dd]
                if 0<=nx<and 0<=ny<M:
                    if not visited[nx][ny]:
                        if office[nx][ny]!=6:
                            visited[nx][ny] = 1
                            rollback.append((nx,ny))
                        else:
                            break
                else:
                    break
 
        answer = min(answer,watch(idx+1))
        for rb in rollback:
            bx,by = rb
            if not office[bx][by]:
                visited[bx][by] = 0
        if office[x][y]==5:
            return answer
    return answer
 
N, M = map(int,input().split())
office = []
for _ in range(N):
    office.append(list(map(int,input().split())))
 
visited = [[0 for _ in range(M)] for _ in range(N)]
cctvs = []
cctv_count = 0
answer = N*
for i in range(N):
    for j in range(M):
        if office[i][j] and office[i][j] !=6:
            cctvs.append((i,j))
            visited[i][j] = 1
            cctv_count+=1
answer = watch(0)
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 16918. 봄버맨  (0) 2021.10.14
[BOJ] 16236. 아기 상어  (0) 2021.10.13
[BOJ] 14500. 테트로미노  (0) 2021.10.08
[BOJ]2458. 키 순서  (0) 2021.10.07
[BOJ] 21608. 상어 초등학교  (0) 2021.10.06
728x90
반응형

문제:

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.

  • 정사각형은 서로 겹치면 안 된다.
  • 도형은 모두 연결되어 있어야 한다.
  • 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.

정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.

아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.

테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.

테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

입력:

첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)

둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

출력:

첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

풀이방법:

 정사각형 4개를 이어 붙인 폴리오미노인 테트로미노는 회전과 대칭을 포함해도 경우의 수가 많지 않다. 따라서 모든 경우의 수를 포함하고 있는 shape_list를 만든 후에 모든 점마다 테트로미노를 하나씩 넣어보며 가장 최대가 되는 경우를 찾는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
shape_list = [
    [(0,1),(0,2),(0,3)],
    [(1,0),(2,0),(3,0)],
    [(0,1),(1,0),(1,1)],
    [(1,0),(2,0),(2,1)],
    [(1,0),(0,1),(0,2)],
    [(0,1),(1,1),(2,1)],
    [(0,1),(0,2),(-1,2)],
    [(1,0),(2,0),(2,-1)],
    [(0,1),(0,2),(1,2)],
    [(0,1),(1,0),(2,0)],
    [(1,0),(1,1),(1,2)],
    [(1,0),(1,1),(2,1)],
    [(0,1),(-1,1),(-1,2)],
    [(0,1),(1,0),(-1,1)],
    [(0,1),(1,1),(1,2)],
    [(0,1),(1,1),(0,2)],
    [(0,1),(-1,1),(1,1)],
    [(0,1),(-1,1),(0,2)],
    [(-1,0),(1,0),(0,1)]
]
N, M = map(int,input().split())
 
papers = []
for _ in range(N):
    papers.append(list(map(int,input().split())))
    
answer= 0
for i in range(N):
    for j in range(M):
        for shape in shape_list:
            start = papers[i][j]
            
            for k in range(3):
                nx = i + shape[k][0]
                ny = j + shape[k][1]
                if 0<= nx < N and 0<=ny < M:
                    start+=papers[nx][ny]
            if answer < start:
                answer= start
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 16236. 아기 상어  (0) 2021.10.13
[BOJ] 15683. 감시  (0) 2021.10.12
[BOJ]2458. 키 순서  (0) 2021.10.07
[BOJ] 21608. 상어 초등학교  (0) 2021.10.06
[BOJ] 10157. 자리배정  (0) 2021.10.05
728x90
반응형

문제:

1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여 6번만 키를 비교하였고, 그 결과가 다음과 같다고 하자.

  • 1번 학생의 키 < 5번 학생의 키
  • 3번 학생의 키 < 4번 학생의 키
  • 5번 학생의 키 < 4번 학생의 키
  • 4번 학생의 키 < 2번 학생의 키
  • 4번 학생의 키 < 6번 학생의 키
  • 5번 학생의 키 < 2번 학생의 키

이 비교 결과로부터 모든 학생 중에서 키가 가장 작은 학생부터 자신이 몇 번째인지 알 수 있는 학생들도 있고 그렇지 못한 학생들도 있다는 사실을 아래처럼 그림을 그려 쉽게 확인할 수 있다. a번 학생의 키가 b번 학생의 키보다 작다면, a에서 b로 화살표를 그려서 표현하였다. 

1번은 5번보다 키가 작고, 5번은 4번보다 작기 때문에, 1번은 4번보다 작게 된다. 그러면 1번, 3번, 5번은 모두 4번보다 작게 된다. 또한 4번은 2번과 6번보다 작기 때문에, 4번 학생은 자기보다 작은 학생이 3명이 있고, 자기보다 큰 학생이 2명이 있게 되어 자신의 키가 몇 번째인지 정확히 알 수 있다. 그러나 4번을 제외한 학생들은 자신의 키가 몇 번째인지 알 수 없다.

학생들의 키를 비교한 결과가 주어질 때, 자신의 키가 몇 번째인지 알 수 있는 학생들이 모두 몇 명인지 계산하여 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 학생들의 수 N (2 ≤ N ≤ 500)과 두 학생 키를 비교한 횟수 M (0 ≤ M ≤ N(N-1)/2)이 주어진다. 다음 M개의 각 줄에는 두 학생의 키를 비교한 결과를 나타내는 두 양의 정수 a와 b가 주어진다. 이는 번호가 a인 학생이 번호가 b인 학생보다 키가 작은 것을 의미한다. 

출력:

자신이 키가 몇 번째인지 알 수 있는 학생이 모두 몇 명인지를 출력한다. 

풀이방법:

 자신을 기준으로 다른 사람에게 도달할 수 있다. 즉, 비교를 할 수 있는 사람이 몇명인지 확인하도록 한다. 자신보다 큰 사람과 자신보다 작은 사람이 N-1명이면 자신의 키가 몇 번째인지 알 수 있다.

 따라서 플로이드 와샬을 사용해서 이 문제를 풀도록 한다. 플로이드 와샬은 모든 꼭짓점 쌍 간의 최단 경로의 길이를 알 수 있는 알고리즘인데, 이 문제에 알맞게 몇명과 비교를 할 수 있는지 여부로 수정하여 문제를 해결하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
N, M = map(int,input().split())
graph = [[0 for _ in range(N)] for _ in range(N)]
for _ in range(M):
    a, b = map(int,input().split())
    graph[a-1][b-1= 1
 
for k in range(N):
    for i in range(N):
        for j in range(N):
            if graph[i][j] or (graph[i][k] and graph[k][j]):
                graph[i][j] = 1
                
answer = 0
for i in range(N):
    tmp = 0
    for j in range(N):
        tmp += graph[i][j] + graph[j][i]
    if tmp == N-1:
        answer+=1
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/2458

 

2458번: 키 순서

1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 15683. 감시  (0) 2021.10.12
[BOJ] 14500. 테트로미노  (0) 2021.10.08
[BOJ] 21608. 상어 초등학교  (0) 2021.10.06
[BOJ] 10157. 자리배정  (0) 2021.10.05
[BOJ] 1019. 책 페이지  (0) 2021.10.01

+ Recent posts