728x90
반응형

문제:

김지민은 N명이 참가하는 스타 토너먼트에 진출했다. 토너먼트는 다음과 같이 진행된다. 일단 N명의 참가자는 번호가 1번부터 N번까지 배정받는다. 그러고 난 후에 서로 인접한 번호끼리 스타를 한다. 이긴 사람은 다음 라운드에 진출하고, 진 사람은 그 라운드에서 떨어진다. 만약 그 라운드의 참가자가 홀수명이라면, 마지막 번호를 가진 참가자는 다음 라운드로 자동 진출한다. 다음 라운드에선 다시 참가자의 번호를 1번부터 매긴다. 이때, 번호를 매기는 순서는 처음 번호의 순서를 유지하면서 1번부터 매긴다. 이 말은 1번과 2번이 스타를 해서 1번이 진출하고, 3번과 4번이 스타를 해서 4번이 진출했다면, 4번은 다음 라운드에서 번호 2번을 배정받는다. 번호를 다시 배정받은 후에 한 명만 남을 때까지 라운드를 계속 한다.

마침 이 스타 대회에 임한수도 참가했다. 김지민은 갑자기 스타 대회에서 우승하는 욕심은 없어지고, 몇 라운드에서 임한수와 대결하는지 궁금해졌다. 일단 김지민과 임한수는 서로 대결하기 전까지 항상 이긴다고 가정한다. 1 라운드에서 김지민의 번호와 임한수의 번호가 주어질 때, 과연 김지민과 임한수가 몇 라운드에서 대결하는지 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 참가자의 수 N과 1 라운드에서 김지민의 번호와 임한수의 번호가 순서대로 주어진다. N은 100,000보다 작거나 같은 자연수이고, 김지민의 번호와 임한수의 번호는 N보다 작거나 같은 자연수이고, 서로 다르다.

출력:

첫째 줄에 김지민과 임한수가 대결하는 라운드 번호를 출력한다. 만약 서로 대결하지 않을 때는 -1을 출력한다.

풀이방법:

 주어진 조건에 따라 수행하게 하는 구현문제다. 앞에서부터 순차적으로 두 사람을 뽑은 뒤에 각 사람이 k와 l인지 확인하고, 둘 중 하나에 해당하면 그 사람이 무조건 이기게 한다. 만약 각각 k와 l에 해당하면 반복문을 중단시킨다.(만약 둘다 아니라면 먼저 들어온 사람을 이기게 한다.) 

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
from collections import deque
def game(person):
    round_ = 0
    while person:
        round_+=1
        next_person = deque()
        while person:
            if len(person)==1:
                next_person.append(person.pop())
            else:
                a, b = person.popleft(), person.popleft()
                if a == k:
                    if b==l:
                        return round_
                    else:
                        next_person.append(a)
                elif a == l:
                    if b==k:
                        return round_
                    else:
                        next_person.append(a)
                elif b==l:
                    if a==k:
                        return round_
                    else:
                        next_person.append(b)
                elif b==k:
                    if a==l:
                        return round_
                    else:
                        next_person.append(b)
                else:
                    next_person.append(a)
        person = next_person
    return 0
N, k, l = map(int,input().split())
person = deque(range(1,N+1))
answer = game(person)
if answer:
    print(answer)
else:
    print(-1)
cs

문제링크:

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

 

1057번: 토너먼트

김지민은 N명이 참가하는 스타 토너먼트에 진출했다. 토너먼트는 다음과 같이 진행된다. 일단 N명의 참가자는 번호가 1번부터 N번까지 배정받는다. 그러고 난 후에 서로 인접한 번호끼리 스타를

www.acmicpc.net

 

728x90
반응형

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

[BOJ]1351. 무한 수열  (0) 2021.09.24
[BOJ]1202. 보석 도둑  (0) 2021.09.23
[BOJ] 14890. 경사로  (0) 2021.09.15
[BOJ]14719. 빗물  (0) 2021.09.14
[BOJ]2470. 두 용액  (0) 2021.09.13
728x90
반응형

문제:

크기가 N×N인 지도가 있다. 지도의 각 칸에는 그 곳의 높이가 적혀져 있다.

오늘은 이 지도에서 지나갈 수 있는 길이 몇 개 있는지 알아보려고 한다. 길이란 한 행 또는 한 열 전부를 나타내며, 한쪽 끝에서 다른쪽 끝까지 지나가는 것이다. 

다음과 같은 N=6인 경우 지도를 살펴보자.

이때, 길은 총 2N개가 있으며, 아래와 같다.

길을 지나갈 수 있으려면 길에 속한 모든 칸의 높이가 모두 같아야 한다. 또는, 경사로를 놓아서 지나갈 수 있는 길을 만들 수 있다. 경사로는 높이가 항상 1이며, 길이는 L이다. 또, 개수는 매우 많아 부족할 일이 없다. 경사로는 낮은 칸과 높은 칸을 연결하며, 아래와 같은 조건을 만족해야한다.

  • 경사로는 낮은 칸에 놓으며, L개의 연속된 칸에 경사로의 바닥이 모두 접해야 한다.
  • 낮은 칸과 높은 칸의 높이 차이는 1이어야 한다.
  • 경사로를 놓을 낮은 칸의 높이는 모두 같아야 하고, L개의 칸이 연속되어 있어야 한다.

아래와 같은 경우에는 경사로를 놓을 수 없다.

  • 경사로를 놓은 곳에 또 경사로를 놓는 경우
  • 낮은 칸과 높은 칸의 높이 차이가 1이 아닌 경우
  • 낮은 지점의 칸의 높이가 모두 같지 않거나, L개가 연속되지 않은 경우
  • 경사로를 놓다가 범위를 벗어나는 경우

L = 2인 경우에 경사로를 놓을 수 있는 경우를 그림으로 나타내면 아래와 같다.

경사로를 놓을 수 없는 경우는 아래와 같다.

위의 그림의 가장 왼쪽부터 1번, 2번, 3번, 4번 예제라고 했을 때, 1번은 높이 차이가 1이 아니라서, 2번은 경사로를 바닥과 접하게 놓지 않아서, 3번은 겹쳐서 놓아서, 4번은 기울이게 놓아서 불가능한 경우이다.

가장 위에 주어진 그림 예의 경우에 지나갈 수 있는 길은 파란색으로, 지나갈 수 없는 길은 빨간색으로 표시되어 있으며, 아래와 같다. 경사로의 길이 L = 2이다.

지도가 주어졌을 때, 지나갈 수 있는 길의 개수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

출력:

첫째 줄에 지나갈 수 있는 길의 개수를 출력한다.

풀이방법:

check 함수를 사용해서 가로에 대해서 먼저 체크하고, 행과 열을 바꿔 세로에 대해서 체크하도록 한다.

check 함수 내에서는 현재값과 다음값의 높이 차이에 대해서 확인하고, 같다면 그대로 넘어간다. 만약 차이가 1보다 크다면 경사로를 놓을 수 없는 경우이기 때문에 0을 반환한다.

 만약 1 혹은 -1만큼의 차이가 나면 그 위치로부터 L의 경사로를 놓을 수 있는지 확인한다. 이 때 확인해야 하는 것은 낮은 지점의 높이가 L개 만큼 연속되는지, 이미 경사로가 놓아져 있는지 확인해야 한다. 이 과정이 모두 확인되면 visited배열에 경사로를 놓으며 넘어가고 그렇지 않다면 0을 반환하도록 한다. 이렇게 끝까지 탐색했는데 문제가 없는 경우라면 answer에 1을 더하도록 한다.

 모든 탐색을 마친 뒤에 answer 값을 출력하도록 한다.

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
N, L = map(int,input().split())
 
def check(map_):
    visited = [0]*N
    for i in range(N-1):
        if map_[i]==map_[i+1]:
            continue
        if abs(map_[i]-map_[i+1]) > 1:
            return 0
        if map_[i]-map_[i+1== 1:
            tmp = map_[i+1]
            for j in range(i+1,i+L+1):
                if 0<= j < N:
                    if map_[j]!=tmp:
                        return 0
                    if visited[j]:
                        return 0
                    visited[j] = 1
                else:
                    return 0
        else:
            tmp = map_[i]
            for j in range(i,i-L,-1):
                if 0<= j < N:
                    if map_[j]!=tmp:
                        return 0
                    if visited[j]:
                        return 0
                    visited[j] = 1
                else:
                    return 0
    return 1
        
maps = []
for _ in range(N):
    maps.append(list(map(int,input().split())))
    
answer = 0 
for map_ in maps:
    if check(map_):
        answer+=1
        
maps = list(map(list,zip(*maps)))
for map_ in maps:
    if check(map_):
        answer+=1
        
print(answer)
cs

문제링크:

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

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

 

728x90
반응형

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

[BOJ]1202. 보석 도둑  (0) 2021.09.23
[BOJ]1057. 토너먼트  (0) 2021.09.16
[BOJ]14719. 빗물  (0) 2021.09.14
[BOJ]2470. 두 용액  (0) 2021.09.13
[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
728x90
반응형

문제:

2차원 세계에 블록이 쌓여있다. 비가 오면 블록 사이에 빗물이 고인다.

비는 충분히 많이 온다. 고이는 빗물의 총량은 얼마일까?

입력:

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500)

두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치부터 차례대로 W개 주어진다.

따라서 블록 내부의 빈 공간이 생길 수 없다. 또 2차원 세계의 바닥은 항상 막혀있다고 가정하여도 좋다.

출력:

2차원 세계에서는 한 칸의 용량은 1이다. 고이는 빗물의 총량을 출력하여라.

빗물이 전혀 고이지 않을 경우 0을 출력하여라.

풀이방법:

 양 끝점을 제외한 칸에서부터 왼쪽과 오른쪽을 각각 탐색해서 가장 낮은 위치를 찾아내고, 왼쪽의 가장 낮은 위치와 오른쪽의 가장 낮은 위치 더 낮은 값이 해당 칸에 빗물이 고인 수치다. 이 과정을 모든 칸에 진행하면서 값을 누적시키면 최종 답을 구할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
H, W = map(int,input().split())
block = list(map(int,input().split()))
 
answer = 0
for cur in range(1, W-1):
    left_block = block[cur]
    for i in range(cur-1,-1,-1):
        if left_block < block[i]:
            left_block = block[i]
    right_block = block[cur]
    for j in range(cur+1,W):
        if right_block < block[j]:
            right_block = block[j]
    min_block = min(left_block, right_block)
    answer += min_block-block[cur]
print(answer)
cs

문제링크:

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

 

14719번: 빗물

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치

www.acmicpc.net

 

728x90
반응형

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

[BOJ]1057. 토너먼트  (0) 2021.09.16
[BOJ] 14890. 경사로  (0) 2021.09.15
[BOJ]2470. 두 용액  (0) 2021.09.13
[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
[BOJ]2110. 공유기 설치  (0) 2021.09.09
728x90
반응형

문제:

KOI 부설 과학연구소에서는 많은 종류의 산성 용액과 알칼리성 용액을 보유하고 있다. 각 용액에는 그 용액의 특성을 나타내는 하나의 정수가 주어져있다.  산성 용액의 특성값은 1부터 1,000,000,000까지의 양의 정수로 나타내고, 알칼리성 용액의 특성값은 -1부터 -1,000,000,000까지의 음의 정수로 나타낸다.

같은 양의 두 용액을 혼합한 용액의 특성값은 혼합에 사용된 각 용액의 특성값의 합으로 정의한다. 이 연구소에서는 같은 양의 두 용액을 혼합하여 특성값이 0에 가장 가까운 용액을 만들려고 한다. 

예를 들어, 주어진 용액들의 특성값이 [-2, 4, -99, -1, 98]인 경우에는 특성값이 -99인 용액과 특성값이 98인 용액을 혼합하면 특성값이 -1인 용액을 만들 수 있고, 이 용액이 특성값이 0에 가장 가까운 용액이다. 참고로, 두 종류의 알칼리성 용액만으로나 혹은 두 종류의 산성 용액만으로 특성값이 0에 가장 가까운 혼합 용액을 만드는 경우도 존재할 수 있다.

산성 용액과 알칼리성 용액의 특성값이 주어졌을 때, 이 중 두 개의 서로 다른 용액을 혼합하여 특성값이 0에 가장 가까운 용액을 만들어내는 두 용액을 찾는 프로그램을 작성하시오.

입력:

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,000,000 이하이다. N개의 용액들의 특성값은 모두 다르고, 산성 용액만으로나 알칼리성 용액만으로 입력이 주어지는 경우도 있을 수 있다.

출력:

첫째 줄에 특성값이 0에 가장 가까운 용액을 만들어내는 두 용액의 특성값을 출력한다. 출력해야 하는 두 용액은 특성값의 오름차순으로 출력한다. 특성값이 0에 가장 가까운 용액을 만들어내는 경우가 두 개 이상일 경우에는 그 중 아무것이나 하나를 출력한다.

풀이방법:

 투 포인터를 양쪽 끝값에 두고, 하나씩 이동시키면서 0에 가장 가까운 용액을 만들어 나가도록 한다. 포인터에 있는 값을 비교하고, start 값이 크다면 start를 이동하고, end가 크다면 end를 이동시키도록 한다. 이렇게 생성되는 용액의 특성값과 포인터 값들을 min_heap 정렬해두고, 모든 탐색을 마친 뒤에 min heap의 첫 값을 가져와서 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import heapq
answer = []
= int(input())
solution = sorted(list(map(int,input().split())))
start, end = 0, N-1
while start < end:
    tmp = solution[start]+solution[end]
    if abs(solution[start]) > abs(solution[end]):
        heapq.heappush(answer,(abs(tmp),start,end))
        start+=1
    else:
        heapq.heappush(answer,(abs(tmp),start,end))
        end-=1
answer = heapq.heappop(answer)
print(solution[answer[1]],solution[answer[2]])
cs

문제링크:

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

 

2470번: 두 용액

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00

www.acmicpc.net

 

728x90
반응형

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

[BOJ] 14890. 경사로  (0) 2021.09.15
[BOJ]14719. 빗물  (0) 2021.09.14
[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
[BOJ]2110. 공유기 설치  (0) 2021.09.09
[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08
728x90
반응형

문제:

수빈이는 동생에게 "가운데를 말해요" 게임을 가르쳐주고 있다. 수빈이가 정수를 하나씩 외칠때마다 동생은 지금까지 수빈이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 수빈이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.

예를 들어 수빈이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 수빈이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.

출력:

한 줄에 하나씩 N줄에 걸쳐 수빈이의 동생이 말해야하는 수를 순서대로 출력한다.

풀이방법:

시간 제한이 매우 엄격하게 정해져 있기 때문에 max_heap과 min_heap를 두 개를 사용해서 중간값을 구하도록 한다. 기본적인 아이디어는 양쪽에 채워나가면서 heap으로 정리했을 때, 가운데 값을 기준으로 정렬되는 것을 이용한다. max_heap에는 중간값보다 낮은 값들을 채워나가고, min_heap은 중간값보다 큰 값이 채워지도록 하게 한다. 개수가 짝수개인 경우 두 수 중에 작은 수를 말해야 하기 때문에 max_heap에 있는 값을 출력하도록 한다.  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import heapq
= int(input())
max_h = []
min_h = []
for i in range(N):
    tmp = int(input())
    if len(min_h)==len(max_h):
        heapq.heappush(max_h,(-tmp,tmp))
    else:
        heapq.heappush(min_h, tmp)
    if len(max_h) and len(min_h) and max_h[0][1> min_h[0]:
        a, b = heapq.heappop(max_h)[1], heapq.heappop(min_h)
        heapq.heappush(max_h,(-b,b))
        heapq.heappush(min_h,a)
    print(max_h[0][1])
cs

문제링크:

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

 

1655번: 가운데를 말해요

첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -1

www.acmicpc.net

 

728x90
반응형

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

[BOJ]14719. 빗물  (0) 2021.09.14
[BOJ]2470. 두 용액  (0) 2021.09.13
[BOJ]2110. 공유기 설치  (0) 2021.09.09
[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08
[BOJ]2638. 치즈  (0) 2021.09.06
728x90
반응형

문제:

도현이의 집 N개가 수직선 위에 있다. 각각의 집의 좌표는 x1, ..., xN이고, 집 여러개가 같은 좌표를 가지는 일은 없다.

도현이는 언제 어디서나 와이파이를 즐기기 위해서 집에 공유기 C개를 설치하려고 한다. 최대한 많은 곳에서 와이파이를 사용하려고 하기 때문에, 한 집에는 공유기를 하나만 설치할 수 있고, 가장 인접한 두 공유기 사이의 거리를 가능한 크게 하여 설치하려고 한다.

C개의 공유기를 N개의 집에 적당히 설치해서, 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램을 작성하시오.

입력:

첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가 한 줄에 하나씩 주어진다.

출력:

첫째 줄에 가장 인접한 두 공유기 사이의 최대 거리를 출력한다.

풀이방법:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
N, C = map(int,input().split())
house = sorted([int(input()) for _ in range(N)])
answer = 0
right = house[-1]-house[0]
left = 1
 
while left <= right:
    mid = (left + right)//2
    cur = house[0]
    count = 1
    for i in range(1,len(house)):
        if house[i] >= cur + mid:
            count+=1
            cur = house[i]
    if count >= C:
        left = mid + 1
        answer = mid
    else:
        right = mid - 1
        
print(answer)
cs

문제링크:

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

 

2110번: 공유기 설치

첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2470. 두 용액  (0) 2021.09.13
[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08
[BOJ]2638. 치즈  (0) 2021.09.06
[BOJ]2636. 치즈  (0) 2021.09.03
728x90
반응형

문제:

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의 값은 4이다.

 

배열은 회전 연산을 수행할 수 있다. 회전 연산은 세 정수 (r, c, s)로 이루어져 있고, 가장 왼쪽 윗 칸이 (r-s, c-s), 가장 오른쪽 아랫 칸이 (r+s, c+s)인 정사각형을 시계 방향으로 한 칸씩 돌린다는 의미이다. 배열의 칸 (r, c)는 r행 c열을 의미한다.

예를 들어, 배열 A의 크기가 6×6이고, 회전 연산이 (3, 4, 2)인 경우에는 아래 그림과 같이 회전하게 된다.

회전 연산이 두 개 이상이면, 연산을 수행한 순서에 따라 최종 배열이 다르다.

다음은 배열 A의 크기가 5×6이고, 회전 연산이 (3, 4, 2), (4, 2, 1)인 경우의 예시이다.

배열 A에 (3, 4, 2), (4, 2, 1) 순서로 연산을 수행하면 배열 A의 값은 12, (4, 2, 1), (3, 4, 2) 순서로 연산을 수행하면 15 이다.

배열 A와 사용 가능한 회전 연산이 주어졌을 때, 배열 A의 값의 최솟값을 구해보자. 회전 연산은 모두 한 번씩 사용해야 하며, 순서는 임의로 정해도 된다.

입력:

첫째 줄에 배열 A의 크기 N, M, 회전 연산의 개수 K가 주어진다.

둘째 줄부터 N개의 줄에 배열 A에 들어있는 수 A[i][j]가 주어지고, 다음 K개의 줄에 회전 연산의 정보 r, c, s가 주어진다.

출력:

배열 A의 값의 최솟값을 출력한다.

제한:

  • 3 ≤ N, M ≤ 50
  • 1 ≤ K ≤ 6
  • 1 ≤ A[i][j] ≤ 100
  • 1 ≤ s
  • 1 ≤ r-s < r < r+s ≤ N
  • 1 ≤ c-s < c < c+s ≤ M

풀이방법:

 제시되어 있는 방법대로 구현을 하면 되는 문제다. 다만 회전을 하는 것을 한번 구현한 뒤, 점점 안으로 작게 회전을 해야하고, 모서리 부분을 신경쓰면서 구현을 진행해야 한다.

 점점 작아지는 것은 while과 s를 사용해서 구현할 수 있다. s에 의해서 꼭짓점들이 구해지기 때문에, s를 1씩 빼면서 while 반복문을 사용한다. 종료되는 조건은 가장 왼쪽 윗 칸과 가장 오른쪽 아랫 칸이 작아지는 시점이며, r+s==r-s인 경우다.

 permutation을 사용해서 모든 조건을 구한 뒤에 입력받은 A를 copy한 뒤에 회전 연산을 해서 원래 입력값을 보존하도록 한다.

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
from itertools import permutations
import copy
 
def rotate(coord):
    r, c, s = coord    
    while True:
        if r-s==r+s:
            break
        tmp = None
        for i in range(c-s,c+s+1):
            if tmp is None:
                tmp = A[r-s][i]
            else:
                A[r-s][i], tmp = tmp, A[r-s][i]
        for i in range(r-s+1,r+s+1):
            A[i][c+s], tmp = tmp, A[i][c+s]
        for i in range(c+s-1,c-s-1,-1):
            A[r+s][i], tmp = tmp, A[r+s][i]
        for i in range(r+s-1,r-s-1,-1):
            A[i][c-s], tmp = tmp, A[i][c-s]
        s-=1
    
N, M, K = map(int,input().split())
= []
for _ in range(N):
    A.append(list(map(int,input().split())))
    
commands = []
for _ in range(K):
    r, c, s = map(int,input().split())
    commands.append((r-1, c-1, s))
    
command_lists = list(permutations(commands,K))
answer = float('inf')
for command_list in command_lists:
    A_copy = copy.deepcopy(A)
    for c in command_list:
        rotate(c)
    for i in range(N):
        answer = min(sum(A[i]),answer)
    A = copy.deepcopy(A_copy)
print(answer)    
cs

문제링크:

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

 

17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net

 

728x90
반응형

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

[BOJ]1655. 가운데를 말해요  (0) 2021.09.10
[BOJ]2110. 공유기 설치  (0) 2021.09.09
[BOJ]2638. 치즈  (0) 2021.09.06
[BOJ]2636. 치즈  (0) 2021.09.03
[BOJ] 11054. 가장 긴 바이토닉 부분 수열  (0) 2021.09.02
728x90
반응형

문제:

뿌요뿌요의 룰은 다음과 같다.

필드에 여러 가지 색깔의 뿌요를 놓는다. 뿌요는 중력의 영향을 받아 아래에 바닥이나 다른 뿌요가 나올 때까지 아래로 떨어진다.

뿌요를 놓고 난 후, 같은 색 뿌요가 4개 이상 상하좌우로 연결되어 있으면 연결된 같은 색 뿌요들이 한꺼번에 없어진다. 이때 1연쇄가 시작된다.

뿌요들이 없어지고 나서 위에 다른 뿌요들이 있다면, 역시 중력의 영향을 받아 차례대로 아래로 떨어지게 된다.

아래로 떨어지고 나서 다시 같은 색의 뿌요들이 4개 이상 모이게 되면 또 터지게 되는데, 터진 후 뿌요들이 내려오고 다시 터짐을 반복할 때마다 1연쇄씩 늘어난다.

터질 수 있는 뿌요가 여러 그룹이 있다면 동시에 터져야 하고 여러 그룹이 터지더라도 한번의 연쇄가 추가된다.

남규는 최근 뿌요뿌요 게임에 푹 빠졌다. 이 게임은 1:1로 붙는 대전게임이라 잘 쌓는 것도 중요하지만, 상대방이 터뜨린다면 연쇄가 몇 번이 될지 바로 파악할 수 있는 능력도 필요하다. 하지만 아직 실력이 부족하여 남규는 자기 필드에만 신경 쓰기 바쁘다. 상대방의 필드가 주어졌을 때, 연쇄가 몇 번 연속으로 일어날지 계산하여 남규를 도와주자!

입력:

총 12개의 줄에 필드의 정보가 주어지며, 각 줄에는 6개의 문자가 있다.

이때 .은 빈공간이고 .이 아닌것은 각각의 색깔의 뿌요를 나타낸다.

R은 빨강, G는 초록, B는 파랑, P는 보라, Y는 노랑이다.

입력으로 주어지는 필드는 뿌요들이 전부 아래로 떨어진 뒤의 상태이다. 즉, 뿌요 아래에 빈 칸이 있는 경우는 없다.

출력:

현재 주어진 상황에서 몇연쇄가 되는지 출력한다. 하나도 터지지 않는다면 0을 출력한다.

풀이방법:

 bfs를 사용하는 문제다. 그리고 뿌요는 중력의 영향을 받아 아래에 바닥이나 다른 뿌요가 나올 때까지 아래로 떨어지는 것을 쉽게 구현하기 위해 map과 zip을 사용해서 행과 열의 위치를 바꿔서 문제를 해결했다.

 빈공간이 아닌 뿌요를 만났을 때, bfs를 수행한다. 이 때 탐색한 횟수가 4가 넘으면 방문했던 곳들을 모두 fall_이라는 곳에 다시 저장해 없어질 대상임을 표시한다. 이렇게 모든 뿌요들을 모두 탐색한 뒤에 나중에 한번에 뿌요들을 지우고 떨어지는 행동을 수행하게 한다. 이 과정이 한번이라도 발생했다면 다시 한 번 bfs를 수행하고, 그렇지 않다면 답을 출력하도록 한다.

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
puyo = []
for _ in range(12):
    puyo.append(input())
    
puyo = list(map(list,zip(*puyo)))
puyo_copy = puyo.copy()
 
from collections import deque
dx = [0,1,0,-1]
dy = [1,0,-1,0]
def bfs(i,j):
    queue = deque([(i,j)])
    visited = [[0 for _ in range(12)] for _ in range(6)]
    visited[i][j] = 1
    cnt = 1
    while queue:
        x, y = queue.popleft()
        for k in range(4):
            nx = x + dx[k]
            ny = y + dy[k]
            if 0<= nx < 6 and 0<= ny < 12 and not visited[nx][ny]:
                if puyo_copy[i][j]==puyo_copy[nx][ny]:
                    visited[nx][ny] = 1
                    queue.append((nx,ny))
                    cnt+=1
    if cnt>=4:
        for i in range(6):
            for j in range(12):
                if visited[i][j]:
                    fall_[i][j]=1
        return 1
    else:
        return 0
 
def falling():
    for i,f in enumerate(fall_):
        empty = ['.']*f.count(1)
        puyo_copy[i] = empty + [p for j,p in enumerate(puyo_copy[i]) if not f[j]]
        
time =0
while  True:
    flag=0
    fall_ = [[0 for _ in range(12)] for _ in range(6)]
    for i in range(6):
        for j in range(12):
            if puyo_copy[i][j]!='.':
                flag += bfs(i,j)
    if flag:
        time+=1
    else:
        break
    falling()
    
print(time)
cs

문제링크:

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

 

11559번: Puyo Puyo

총 12개의 줄에 필드의 정보가 주어지며, 각 줄에는 6개의 문자가 있다. 이때 .은 빈공간이고 .이 아닌것은 각각의 색깔의 뿌요를 나타낸다. R은 빨강, G는 초록, B는 파랑, P는 보라, Y는 노랑이다.

www.acmicpc.net

 

728x90
반응형

'Algorithm' 카테고리의 다른 글

[BOJ]13913. 숨바꼭질 4  (0) 2022.08.11
[BOJ]3190. 뱀  (0) 2021.08.19
[BOJ]1520. 내리막길  (0) 2021.08.17
[BOJ]1987. 알파벳  (0) 2021.08.10
[BOJ]14425. 문자열 집합  (0) 2021.06.24
728x90
반응형

문제:

N×M (5≤N, M≤100)의 모눈종이 위에 아주 얇은 치즈가 <그림 1>과 같이 표시되어 있다. 단, N 은 세로 격자의 수이고, M 은 가로 격자의 수이다. 이 치즈는 냉동 보관을 해야만 하는데 실내온도에 내어놓으면 공기와 접촉하여 천천히 녹는다. 그런데 이러한 모눈종이 모양의 치즈에서 각 치즈 격자(작 은 정사각형 모양)의 4변 중에서 적어도 2변 이상이 실내온도의 공기와 접촉한 것은 정확히 한시간만에 녹아 없어져 버린다. 따라서 아래 <그림 1> 모양과 같은 치즈(회색으로 표시된 부분)라면 C로 표시된 모든 치즈 격자는 한 시간 후에 사라진다.

<그림 2>와 같이 치즈 내부에 있는 공간은 치즈 외부 공기와 접촉하지 않는 것으로 가정한다. 그러므 로 이 공간에 접촉한 치즈 격자는 녹지 않고 C로 표시된 치즈 격자만 사라진다. 그러나 한 시간 후, 이 공간으로 외부공기가 유입되면 <그림 3>에서와 같이 C로 표시된 치즈 격자들이 사라지게 된다.

모눈종이의 맨 가장자리에는 치즈가 놓이지 않는 것으로 가정한다. 입력으로 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 구하는 프로그램을 작성하시오.

입력:

첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로 표시된다. 또한, 각 0과 1은 하나의 공백으로 분리되어 있다.

출력:

출력으로는 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 첫 줄에 출력한다.

풀이방법:

https://codedrive.tistory.com/470

2636. 치즈 문제에서 조건이 하나 더 추가된 문제다. 2636 문제에 delete 배열을 이용해서 접한 횟수를 추가적으로 세서, 2 이상인 경우에만 치즈가 녹게 하면 된다.

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
from collections import deque
 
dx = [0,1,0,-1]
dy = [1,0,-1,0]
 
def bfs(i,j):
    queue = deque([(i,j)])
    visited = [[0 for _ in range(M)] for _ in range(N)]
    visited[i][j] = -1
    exist = False
    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 < M and not visited[nx][ny]:
                if cheese[nx][ny]:
                    delete[nx][ny]+=1
                    exist = True
                else:
                    visited[nx][ny] = -1
                    queue.append((nx,ny))
    for i in range(N):
        for j in range(M):
            if delete[i][j] >= 2:
                cheese[i][j] = 0
    return exist
 
N, M = map(int,input().split())
cheese = []
for _ in range(N):
    cheese.append(list(map(int,input().split())))
    
time = 0
while True:
    delete = [[0 for _ in range(M)] for _ in range(N)]
    conti = bfs(0,0)
    if conti:
        time+=1
    else:
        break
print(time)
cs

문제링크:

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

 

2638번: 치즈

첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로

www.acmicpc.net

 

728x90
반응형

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

[BOJ]2110. 공유기 설치  (0) 2021.09.09
[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08
[BOJ]2636. 치즈  (0) 2021.09.03
[BOJ] 11054. 가장 긴 바이토닉 부분 수열  (0) 2021.09.02
[BOJ]2565. 전깃줄  (0) 2021.09.01
728x90
반응형

문제:

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓여 있지 않으며 치즈에는 하나 이상의 구멍이 있을 수 있다.

이 치즈를 공기 중에 놓으면 녹게 되는데 공기와 접촉된 칸은 한 시간이 지나면 녹아 없어진다. 치즈의 구멍 속에는 공기가 없지만 구멍을 둘러싼 치즈가 녹아서 구멍이 열리면 구멍 속으로 공기가 들어가게 된다. <그림 1>의 경우, 치즈의 구멍을 둘러싼 치즈는 녹지 않고 ‘c’로 표시된 부분만 한 시간 후에 녹아 없어져서 <그림 2>와 같이 된다.

다시 한 시간 후에는 <그림 2>에서 ‘c’로 표시된 부분이 녹아 없어져서 <그림 3>과 같이 된다.

<그림 3>은 원래 치즈의 두 시간 후 모양을 나타내고 있으며, 남은 조각들은 한 시간이 더 지나면 모두 녹아 없어진다. 그러므로 처음 치즈가 모두 녹아 없어지는 데는 세 시간이 걸린다. <그림 3>과 같이 치즈가 녹는 과정에서 여러 조각으로 나누어 질 수도 있다.

입력으로 사각형 모양의 판의 크기와 한 조각의 치즈가 판 위에 주어졌을 때, 공기 중에서 치즈가 모두 녹아 없어지는 데 걸리는 시간과 모두 녹기 한 시간 전에 남아있는 치즈조각이 놓여 있는 칸의 개수를 구하는 프로그램을 작성하시오.

입력:

첫째 줄에는 사각형 모양 판의 세로와 가로의 길이가 양의 정수로 주어진다. 세로와 가로의 길이는 최대 100이다. 판의 각 가로줄의 모양이 윗 줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다. 치즈가 없는 칸은 0, 치즈가 있는 칸은 1로 주어지며 각 숫자 사이에는 빈칸이 하나씩 있다.

출력:

첫째 줄에는 치즈가 모두 녹아서 없어지는 데 걸리는 시간을 출력하고, 둘째 줄에는 모두 녹기 한 시간 전에 남아있는 치즈조각이 놓여 있는 칸의 개수를 출력한다.

풀이방법:

 일반적인 bfs와 다르게 이 치즈 문제에서는 '치즈 안에 빈 공간이 있는 경우에는 녹지 않는다' 라는 조건이 있기 때문에, 이를 신경써야 한다. 따라서 치즈를 기준으로 bfs를 하는 것이 아니라 공기를 기준으로 bfs를 수행하며 치즈를 만난 경우에 탐색을 종료하고 기록하는 방식으로 한다.

 0,0은 항상 공기이기 때문에(판의 가장자리) 이 점으로부터 시작해서 bfs를 수행하고, 모든 탐색을 마친 뒤에 한 번에 치즈를 녹이도록 한다. 이를 치즈가 모두 녹을 때까지 반복한다.

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
from collections import deque
import sys
 
#input = sys.stdin.readline
 
dx = [0,1,0,-1]
dy = [1,0,-1,0]
 
def bfs(count):
    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 < M and not visited[nx][ny]:
                visited[nx][ny] = 1
                if cheese[nx][ny]==1:
                    cheese[nx][ny] = -1
                    count-=1
                else:
                    queue.append((nx,ny))
    return count
 
def melt():
    for i in range(N):
        for j in range(M):
            if cheese[i][j] == -1:
                cheese[i][j] = 0
 
N,M = map(int,input().split())
cheese = []
count = 0
for _ in range(N):
    sub_cheese = list(map(int,input().split()))
    count += sum(sub_cheese)
    cheese.append(sub_cheese)
    
time = 0
answer = count
queue = deque()
while count:
    visited = [[0 for _ in range(M)] for _ in range(N)]
    queue.append((0,0))
    visited[0][0= 1
    count = bfs(count)
    
    if count:
        answer = count
        
    time+=1
    melt()
    
print(time)
print(answer)
cs

문제링크:

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

 

2636번: 치즈

첫째 줄에는 사각형 모양 판의 세로와 가로의 길이가 양의 정수로 주어진다. 세로와 가로의 길이는 최대 100이다. 판의 각 가로줄의 모양이 윗 줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진

www.acmicpc.net

 

728x90
반응형

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

[BOJ]17406. 배열 돌리기 4  (0) 2021.09.08
[BOJ]2638. 치즈  (0) 2021.09.06
[BOJ] 11054. 가장 긴 바이토닉 부분 수열  (0) 2021.09.02
[BOJ]2565. 전깃줄  (0) 2021.09.01
[BOJ]2042. 구간 합 구하기  (0) 2021.08.31

+ Recent posts