문제:

시골에 있는 태양이의 삼촌 댁에는 커다란 참외밭이 있다. 문득 태양이는 이 밭에서 자라는 참외가 도대체 몇 개나 되는지 궁금해졌다. 어떻게 알아낼 수 있는지 골똘히 생각하다가 드디어 좋은 아이디어가 떠올랐다. 유레카! 1m2의 넓이에 자라는 참외 개수를 헤아린 다음, 참외밭의 넓이를 구하면 비례식을 이용하여 참외의 총개수를 구할 수 있다.

1m2의 넓이에 자라는 참외의 개수는 헤아렸고, 이제 참외밭의 넓이만 구하면 된다. 참외밭은 ㄱ-자 모양이거나 ㄱ-자를 90도, 180도, 270도 회전한 모양(┏, ┗, ┛ 모양)의 육각형이다. 다행히도 밭의 경계(육각형의 변)는 모두 동서 방향이거나 남북 방향이었다. 밭의 한 모퉁이에서 출발하여 밭의 둘레를 돌면서 밭경계 길이를 모두 측정하였다.

예를 들어 참외밭이 위 그림과 같은 모양이라고 하자. 그림에서 오른쪽은 동쪽, 왼쪽은 서쪽, 아래쪽은 남쪽, 위쪽은 북쪽이다. 이 그림의 왼쪽위 꼭짓점에서 출발하여, 반시계방향으로 남쪽으로 30m, 동쪽으로 60m, 남쪽으로 20m, 동쪽으로 100m, 북쪽으로 50m, 서쪽으로 160m 이동하면 다시 출발점으로 되돌아가게 된다.

위 그림의 참외밭  면적은 6800m2이다. 만약 1m2의 넓이에 자라는 참외의 개수가 7이라면, 이 밭에서 자라는 참외의 개수는 47600으로 계산된다.

1m2의 넓이에 자라는 참외의 개수와, 참외밭을 이루는 육각형의 임의의 한 꼭짓점에서 출발하여 반시계방향으로 둘레를 돌면서 지나는 변의 방향과 길이가 순서대로 주어진다. 이 참외밭에서 자라는 참외의 수를 구하는 프로그램을 작성하시오.

입력:

첫 번째 줄에 1m2의 넓이에 자라는 참외의 개수를 나타내는 양의 정수 K (1 ≤ K ≤ 20)가 주어진다. 참외밭을 나타내는 육각형의 임의의 한 꼭짓점에서 출발하여 반시계방향으로 둘레를 돌면서 지나는 변의 방향과 길이 (1 이상 500 이하의 정수) 가 둘째 줄부터 일곱 번째 줄까지 한 줄에 하나씩 순서대로 주어진다. 변의 방향에서 동쪽은 1, 서쪽은 2, 남쪽은 3, 북쪽은 4로 나타낸다.

출력:

첫째 줄에 입력으로 주어진 밭에서 자라는 참외의 수를 출력한다.

풀이방법:

 참외밭의 모양은 ㄱ-자 이거나 해당 모양의 회전 형태로 구성되어 있다. 이러한 모양의 넓이는 구하는 방법은 아래 그림을 참고하면 쉽게 구할 수 있다.

 이 문제에서 원하는 넓이는 노란색 영역의 넓이다. 해당 넓이를 (노랑+빨강) 직사각형에서 빨강의 직사각형을 빼는 방식으로 쉽게 구할 수 있다. 따라서 이 문제에서 해야할 것은 가장 긴 가로 길이와 가장 긴 세로 길이를 구하고, 이를 통해 작은 직사각형의 넓이를 구하는 것이다.

 입력으로 주어진 방향과 길이 배열을 한번씩 순회하면서 가장 긴 가로, 세로 길이를 구하고 배열의 인덱스를 저장한다. 그러면 가장 긴 가로, 세로 인덱스를 기준으로 양 옆의 길이 차를 계산하면 작은 직사각형의 가로 및 세로 길이를 구할 수 있게 된다.

 최종적으로 큰 직사각형과 작은 직사각형의 가로, 세로 길이를 모두 알 수 있게 되었으므로 이 둘의 차를 구한 뒤 K 값을 곱해주도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
= int(input())
 
melon = []
for _ in range(6):
    p, l = map(int, input().split())
    melon.append((p, l))
 
w, w_idx = 00
h, h_idx = 00
for i in range(len(melon)):
    if melon[i][0]==1 or melon[i][0]==2:
        if w < melon[i][1]:
            w = melon[i][1]
            w_idx = i
    elif melon[i][0]==3 or melon[i][0]==4:
        if h < melon[i][1]:
            h = melon[i][1]
            h_idx = i
 
sub_w = abs(melon[(w_idx-1)%6][1- melon[((w_idx+1)%6)][1])
sub_h = abs(melon[(h_idx-1)%6][1- melon[((h_idx+1)%6)][1])
 
print((w*- sub_w*sub_h)*K)
cs

문제링크:

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

 

2477번: 참외밭

첫 번째 줄에 1m2의 넓이에 자라는 참외의 개수를 나타내는 양의 정수 K (1 ≤ K ≤ 20)가 주어진다. 참외밭을 나타내는 육각형의 임의의 한 꼭짓점에서 출발하여 반시계방향으로 둘레를 돌면서 지

www.acmicpc.net

 

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

[Programmers]Lv 2. 택배상자  (0) 2023.07.05
[1138] 한 줄로 서기  (0) 2023.07.04
[BOJ]14620. 꽃길  (1) 2022.08.18
[BOJ]14497. 주난의 난(難)  (0) 2022.08.16
[BOJ]12851. 숨바꼭질 2  (0) 2022.08.09

문제:

2017년 4월 5일 식목일을 맞이한 진아는 나무를 심는 대신 하이테크관 앞 화단에 꽃을 심어 등교할 때 마다 꽃길을 걷고 싶었다.

진아가 가진 꽃의 씨앗은 꽃을 심고나면 정확히 1년후에 꽃이 피므로 진아는 다음해 식목일 부터 꽃길을 걸을 수 있다.

하지만 진아에게는 꽃의 씨앗이 세개밖에 없었으므로 세 개의 꽃이 하나도 죽지 않고 1년후에 꽃잎이 만개하길 원한다.

꽃밭은 N*N의 격자 모양이고 진아는 씨앗을 (1,1)~(N,N)의 지점 중 한곳에 심을 수 있다. 꽃의 씨앗은 그림 (a)처럼 심어지며 1년 후 꽃이 피면 그림 (b)모양이 된다.

꽃을 심을 때는 주의할 점이있다. 어떤 씨앗이 꽃이 핀 뒤 다른 꽃잎(혹은 꽃술)과 닿게 될 경우 두 꽃 모두 죽어버린다. 또 화단 밖으로 꽃잎이 나가게 된다면 그 꽃은 죽어버리고 만다.

그림(c)는 세 꽃이 정상적으로 핀 모양이고 그림(d)는 두 꽃이 죽어버린 모양이다.

하이테크 앞 화단의 대여 가격은 격자의 한 점마다 다르기 때문에 진아는 서로 다른 세 씨앗을 모두 꽃이 피게하면서 가장 싼 가격에 화단을 대여하고 싶다.

단 화단을 대여할 때는 꽃잎이 핀 모양을 기준으로 대여를 해야하므로 꽃 하나당 5평의 땅을 대여해야만 한다.

돈이 많지 않은 진아를 위하여 진아가 꽃을 심기 위해 필요한 최소비용을 구해주자!

입력:

입력의 첫째 줄에 화단의 한 변의 길이 N(6≤N≤10)이 들어온다.

이후 N개의 줄에 N개씩 화단의 지점당 가격(0≤G≤200)이 주어진다.

출력:

꽃을 심기 위한 최소 비용을 출력한다.

풀이방법:

화단의 한 변의 길이가 가장 큰 경우는 10이며, 꽃은 3개를 심을 수 있다. 이 때 양 끝 라인들은 꽃을 심을 경우 화단 밖으로 꽃잎이 나가게 되므로, 심지 못하는 구간이다. 따라서 8x8의 점에서 3개를 선택하는 것과 같다. 많지 않은 케이스를 가지고 있으므로, 모든 경우의 수를 구하고, 가능한지 여부를 파악한다. 그래서 가능한 경우에 비용만을 체크하여 최소 비용을 찾는다.

 따라서 combination을 사용하여 모든 케이스를 확인하고, 각 케이스에 대해 한 번의 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
from itertools import combinations
 
dx = [-1010]
dy = [010-1]
 
def check(flowers):
    global answer
    flower_range = []
    cost = 0
    for x, y in flowers:
        flower_range.append((x,y))
        cost += maps[x][y]
        for i in range(4):
            nx = x +dx[i]
            ny = y +dy[i]
            if (nx,ny) not in flower_range:
                flower_range.append((nx, ny))
                cost += maps[nx][ny]
            else:
                return
    answer = min(answer, cost)
 
= int(input())
maps = []
for _ in range(N):
    maps.append(list(map(int,input().split())))
 
candidates = [(x, y) for x in range(1, N-1for y in range(1, N-1)]
answer = float('inf'
for can in combinations(candidates, 3):
    check(can)
print(answer)
cs

문제링크:

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

 

14620번: 꽃길

2017년 4월 5일 식목일을 맞이한 진아는 나무를 심는 대신 하이테크관 앞 화단에 꽃을 심어 등교할 때 마다 꽃길을 걷고 싶었다. 진아가 가진 꽃의 씨앗은 꽃을 심고나면 정확히 1년후에 꽃이 피므

www.acmicpc.net

 

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

[1138] 한 줄로 서기  (0) 2023.07.04
[2477] 참외밭  (0) 2023.07.03
[BOJ]14497. 주난의 난(難)  (0) 2022.08.16
[BOJ]12851. 숨바꼭질 2  (0) 2022.08.09
[BOJ]1189. 컴백홈  (0) 2022.08.04

문제:

주난이는 크게 화가 났다. 책상 서랍 안에 몰래 먹으려고 숨겨둔 초코바가 사라졌기 때문이다. 주난이는 미쳐 날뛰기 시작했다. 사실, 진짜로 뛰기 시작했다.

‘쿵... 쿵...’

주난이는 점프의 파동으로 주변의 모든 친구들을 쓰러뜨리고(?) 누군가 훔쳐간 초코바를 찾으려고 한다. 주난이는 N×M크기의 학교 교실 어딘가에서 뛰기 시작했다. 주난이의 파동은 상하좌우 4방향으로 친구들을 쓰러뜨릴(?) 때 까지 계속해서 퍼져나간다. 다르게 표현해서, 한 번의 점프는 한 겹의 친구들을 쓰러뜨린다. 다음의 예를 보자.

1 # 1 0 1 1 1
1 1 0 1 0 0 1
0 0 1 * 1 1 1
1 1 0 1 1 1 1
0 0 1 1 0 0 1

 

주난이를 뜻하는 *은 (3, 4)에 있고, 초코바를 가진 학생 #는 (1, 2)에 있다. 0은 장애물이 없는 빈 공간임을 뜻하고, 1은 친구들이 서있음을 의미한다. 다음은 주난이의 점프에 따른 생존(?) 학생들의 변화이다.

1 # 1 0 1 1 1
1 1 0 0 0 0 1
0 0 0 * 0 1 1
1 1 0 0 1 1 1
0 0 1 1 0 0 1

 

1 # 0 0 0 0 1
0 0 0 0 0 0 0
0 0 0 * 0 0 1
0 0 0 0 0 1 1
0 0 0 0 0 0 1

 

0 X 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 * 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0

위의 예시에서 주난이는 3번의 점프 만에 초코바를 훔쳐간 범인을 찾아낼 수 있다!

주난이를 빨리 멈춰야 교실의 안녕을 도모할 수 있다. 주난이에게 최소 점프 횟수를 알려줘서 교실을 지키자.

입력:

첫째 줄에 주난이가 위치한 교실의 크기 N, M이 주어진다. (1 ≤ N, M ≤ 300)

둘째 줄에 주난이의 위치 x1, y1과 범인의 위치 x2, y2가 주어진다. (1 ≤ x1, x2 ≤ N, 1 ≤ y1, y2 ≤ M)

이후 N×M 크기의 교실 정보가 주어진다. 0은 빈 공간, 1은 친구, *는 주난, #는 범인을 뜻한다.

출력:

주난이가 범인을 잡기 위해 최소 몇 번의 점프를 해야 하는지 출력한다.

풀이방법:

 한 번의 점프가 한 겹의 친구들을 쓰러뜨리고, 친구들을 쓰러뜨릴(?) 때 까지 반복한다는 것은 BFS를 반복적으로 사용한다는 것과 같다. 따라서 시작점으로부터 상하좌우로 BFS를 수행하도록 한다.

 여기서 한 번의 점프가 단순히 한번 상하좌우로 움직이는 것이 아니라 상하좌우로 모두 친구들을 쓰러뜨리는 것이다. 따라서 BFS를 탐색할 때, 친구가 있거나 초코바가 있다면 queue의 우측에 값을 넣도록 하고(다음 점프임을 의미), 그렇지 않다면 queue의 왼쪽에 값을 넣도록 한다(같은 점프 내에 쓰러져야함). visited 개념을 distance로 사용하여 몇 번째 점프인지 기록하도록 한다.

 이렇게 모든 점프를 마친 뒤에 초코바 위치에 있는 distance를 출력하도록 한다.

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
from collections import deque
 
N, M = map(int,input().split())
x1, y1, x2, y2 = map(int,input().split())
maps = []
distance = [[-1 for _ in range(M)] for _ in range(N)]
for _ in range(N):
    maps.append(list(input()))
    
dx = [-1010]
dy = [0-101]
 
queue = deque([(x1-1,y1-1)])
distance[x1-1][y1-1= 0 
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 distance[nx][ny]==-1:
            if maps[nx][ny]=="1" or maps[nx][ny]=='#':
                distance[nx][ny] = distance[x][y]+1
                queue.append((nx, ny))
            elif maps[nx][ny]=='0':
                distance[nx][ny] = distance[x][y]
                queue.appendleft((nx,ny))
print(distance[x2-1][y2-1])
cs

문제링크:

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

 

14497번: 주난의 난(難)

주난이는 크게 화가 났다. 책상 서랍 안에 몰래 먹으려고 숨겨둔 초코바가 사라졌기 때문이다. 주난이는 미쳐 날뛰기 시작했다. 사실, 진짜로 뛰기 시작했다. ‘쿵... 쿵...’ 주난이는 점프의 파

www.acmicpc.net

 

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

[2477] 참외밭  (0) 2023.07.03
[BOJ]14620. 꽃길  (1) 2022.08.18
[BOJ]12851. 숨바꼭질 2  (0) 2022.08.09
[BOJ]1189. 컴백홈  (0) 2022.08.04
[BOJ]12869.뮤탈리스크  (0) 2022.08.02

문제:

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.

입력:

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

출력:

첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

둘째 줄에 어떻게 이동해야 하는지 공백으로 구분해 출력한다.

풀이방법:

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

 

12851번: 숨바꼭질 2

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때

www.acmicpc.net

 

2022.08.09 - [Algorithm/Python] - [BOJ]12851. 숨바꼭질 2

 이전 문제의 발전된 버전으로 가장 빠른 시간과 그 시간으로 이동한 경로를 출력해야 하는 문제다. 위 문제 해결 방법에 추가적으로 visited 배열을 이전에는 0과 1의 여부로만 사용했지만 count 값을 저장하도록 하여 최소 시간을 측정할 수 있도록 했다. 그리고 path라는 배열을 사용해서 이동한 점의 위치에 기존에 있었던 점의 값을 저장하도록 하여, 동생이 위치한 점에 도달했을 때, 역추론이 가능하도록 한다.

 역추론을 하기 위한 print_path라는 함수가 존재하며 history를 만든 후 이를 뒤집어서 출력하도록 한다.

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
from collections import deque
 
def print_path(now):
    history = []
    temp = now
    for _ in range(visited[now]+1):
        history.append(temp)
        temp = path[temp]
    print(" ".join(map(str, history[::-1])))
    
N, K = map(int,input().split())
visited = [0]*100001
path = [0]*100001
queue = deque([[N, 0]])
while queue:
    point, count = queue.popleft()
    if point==K:
        print(visited[point])
        print_path(point)
        break
    if point-1>=0 and not visited[point-1]:
        queue.append([point-1,count+1])
        visited[point-1]=count+1
        path[point-1= point
    if point+1<=100000 and not visited[point+1]:
        queue.append([point+1,count+1])
        visited[point+1]=count+1
        path[point+1= point
    if 2*point<=100000 and not visited[2*point]:
        queue.append([2*point,count+1])     
        visited[2*point]=count+1
        path[2*point] = point
cs

문제링크:

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

 

13913번: 숨바꼭질 4

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

 

'Algorithm' 카테고리의 다른 글

[BOJ]11559. Puyo Puyo  (0) 2021.09.07
[BOJ]3190. 뱀  (0) 2021.08.19
[BOJ]1520. 내리막길  (0) 2021.08.17
[BOJ]1987. 알파벳  (0) 2021.08.10
[BOJ]14425. 문자열 집합  (0) 2021.06.24

문제:

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 그리고, 가장 빠른 시간으로 찾는 방법이 몇 가지 인지 구하는 프로그램을 작성하시오.

입력:

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

출력:

첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

둘째 줄에는 가장 빠른 시간으로 수빈이가 동생을 찾는 방법의 수를 출력한다.

풀이방법:

BFS를 사용하여 수빈이가 이동할 수 있는 거리내에서 동생이 있는 위치에 도달하는 시간을 측정하도록 한다.

수빈이가 이동할 수 있는 방법은 총 3가지이므로, 이동할 점이 가능한 범위 내에 존재하고 이전에 도달한 적이 없는 곳이라면 queue에 넣고 이동하도록 한다. 그러다 동생이 있는 위치에 도달하면 해당 시간의 count를 하나 증가 시키고, 모든 탐색을 마친 뒤에는 시간, count의 dict에서 최소 시간의 count를 출력하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from collections import deque, defaultdict
N, K = map(int,input().split())
visited = [0]*100001
answer = defaultdict(int)
queue = deque([[N, 0]])
while queue:
    point, count = queue.popleft()
    visited[point]=1
    if point==K:
        answer[count]+=1
    if point-1>=0 and not visited[point-1]:
        queue.append([point-1,count+1])
    if point+1<=100000 and not visited[point+1]:
        queue.append([point+1,count+1])
    if 2*point<=100000 and not visited[2*point]:
        queue.append([2*point,count+1])     
 
answer = sorted(answer.items())
print(answer[0][0])
print(answer[0][1])
cs

문제링크:

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

 

12851번: 숨바꼭질 2

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때

www.acmicpc.net

 

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

[BOJ]14620. 꽃길  (1) 2022.08.18
[BOJ]14497. 주난의 난(難)  (0) 2022.08.16
[BOJ]1189. 컴백홈  (0) 2022.08.04
[BOJ]12869.뮤탈리스크  (0) 2022.08.02
[BOJ]2852. NBA 농구  (0) 2022.07.28

문제:

한수는 캠프를 마치고 집에 돌아가려 한다. 한수는 현재 왼쪽 아래점에 있고 집은 오른쪽 위에 있다. 그리고 한수는 집에 돌아가는 방법이 다양하다. 단, 한수는 똑똑하여 한번 지나친 곳을 다시 방문하지는 않는다.

      cdef  ...f  ..ef  ..gh  cdeh  cdej  ...f 
      bT..  .T.e  .Td.  .Tfe  bTfg  bTfi  .Tde 
      a...  abcd  abc.  abcd  a...  a.gh  abc. 
거리 :  6     6     6     8     8    10    6

위 예제는 한수가 집에 돌아갈 수 있는 모든 경우를 나타낸 것이다. T로 표시된 부분은 가지 못하는 부분이다. 문제는 R x C 맵에 못가는 부분이 주어지고 거리 K가 주어지면 한수가 집까지도 도착하는 경우 중 거리가 K인 가짓수를 구하는 것이다.

입력:

첫 줄에 정수 R(1 ≤ R ≤ 5), C(1 ≤ C ≤ 5), K(1 ≤ K ≤ R×C)가 공백으로 구분되어 주어진다. 두 번째부터 R+1번째 줄까지는 R×C 맵의 정보를 나타내는 '.'과 'T'로 구성된 길이가 C인 문자열이 주어진다.

출력:

첫 줄에 거리가 K인 가짓수를 출력한다.

풀이방법:

 DFS를 사용해서 시작점에서 도착점까지 이동하고, 한 번의 이동마다 거리를 하나씩 늘린다. 도착점에 도달한 경우 거리가 K와 같다면 answer를 하나 증가시키고, 그렇지 않다면 다시 되돌아 오는 과정을 수행한다. '다시 되돌아 온다' 라는 행동을 하기 위해 visited 배열을 사용하고, 그 위치로 이동한 경우에는 해당 좌표의 값을 1로 바꾸고, 다시 되돌아 온 경우에는 0으로 다시 바꿔주도록 한다.

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
dx = [-10 , 10]
dy = [0-10 , 1]
 
from collections import deque
 
def dfs(x, y, count):
    global answer
    visited[x][y]=1
    if [x,y]==[0, C-1]:
        if count==K:
            answer+=1
        return
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if 0<= nx < R and 0 <= ny < C  and visited[nx][ny]==0 and maps[nx][ny]!='T':
            visited[nx][ny]=1
            dfs(nx,ny,count+1)
            visited[nx][ny]=0
            
R, C, K = map(int,input().split())
maps = [list(input()) for _ in range(R)]
visited = [[0 for _ in range(C)] for _ in range(R)]
answer= 0
dfs(R-101)
print(answer)
cs

문제링크:

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

 

1189번: 컴백홈

첫 줄에 정수 R(1 ≤ R ≤ 5), C(1 ≤ C ≤ 5), K(1 ≤ K ≤ R×C)가 공백으로 구분되어 주어진다. 두 번째부터 R+1번째 줄까지는 R×C 맵의 정보를 나타내는 '.'과 'T'로 구성된 길이가 C인 문자열이 주어진다

www.acmicpc.net

 

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

[BOJ]14497. 주난의 난(難)  (0) 2022.08.16
[BOJ]12851. 숨바꼭질 2  (0) 2022.08.09
[BOJ]12869.뮤탈리스크  (0) 2022.08.02
[BOJ]2852. NBA 농구  (0) 2022.07.28
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26

문제:

수빈이는 강호와 함께 스타크래프트 게임을 하고 있다. 수빈이는 뮤탈리스크 1개가 남아있고, 강호는 SCV N개가 남아있다.

각각의 SCV는 남아있는 체력이 주어져있으며, 뮤탈리스크를 공격할 수는 없다. 즉, 이 게임은 수빈이가 이겼다는 것이다.

뮤탈리스크가 공격을 할 때, 한 번에 세 개의 SCV를 공격할 수 있다.

  1. 첫 번째로 공격받는 SCV는 체력 9를 잃는다.
  2. 두 번째로 공격받는 SCV는 체력 3을 잃는다.
  3. 세 번째로 공격받는 SCV는 체력 1을 잃는다.

SCV의 체력이 0 또는 그 이하가 되어버리면, SCV는 그 즉시 파괴된다. 한 번의 공격에서 같은 SCV를 여러 번 공격할 수는 없다.

남아있는 SCV의 체력이 주어졌을 때, 모든 SCV를 파괴하기 위해 공격해야 하는 횟수의 최솟값을 구하는 프로그램을 작성하시오.

입력:

첫째 줄에 SCV의 수 N (1 ≤ N ≤ 3)이 주어진다. 둘째 줄에는 SCV N개의 체력이 주어진다. 체력은 60보다 작거나 같은 자연수이다.

출력:

첫째 줄에 모든 SCV를 파괴하기 위한 공격 횟수의 최솟값을 출력한다.

풀이방법:

 SCV는 최대 3개까지만 있을 수 있기 때문에 이보다 더 적은 SCV가 들어온다면 0 배열을 이어 붙여서 길이가 3인 배열로 만들어 주도록 한다. SCV는 최대 체력이 60이고, 몇번째로 공격받느냐에 따라 체력이 달라지기 때문에 60의 길이를 가지는 3차원 visited 배열을 만든다.

 이후로는 BFS를 사용하여 나올 수 있는 경우의 수를 기반으로 체력을 감소시키며 모두 0이 되는 순간이 정답이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from itertools import permutations
from collections import deque
def bfs():
    q = deque([[scv, 0]])
    
    while q:
        state, count = q.popleft()
        if len(list(filter(lambda x: x>0, state)))==0:            
            break
        for attack in attacks:
            next_state = [0]*3
            for i in range(3):
                next_state[i] = max(0, state[i]-attack[i])
            if not visited[next_state[0]][next_state[1]][next_state[2]]:
                visited[next_state[0]][next_state[1]][next_state[2]] = 1
                q.append([next_state, count+1])
    return count
        
= int(input())
scv = list(map(int,input().split()))+[0]*(3-N)
visited = [[[0 for _ in range(61)]for _ in range(61)]for _ in range(61)]
attacks = list(permutations([9,3,1],3))
print(bfs())
cs

문제링크:

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

 

12869번: 뮤탈리스크

1, 3, 2 순서대로 공격을 하면, 남은 체력은 (12-9, 10-1, 4-3) = (3, 9, 1)이다. 2, 1, 3 순서대로 공격을 하면, 남은 체력은 (0, 0, 0)이다.

www.acmicpc.net

 

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

[BOJ]12851. 숨바꼭질 2  (0) 2022.08.09
[BOJ]1189. 컴백홈  (0) 2022.08.04
[BOJ]2852. NBA 농구  (0) 2022.07.28
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]10709. 기상캐스터  (0) 2022.07.21

문제:

동혁이는 NBA 농구 경기를 즐겨 본다. 동혁이는 골이 들어갈 때 마다 골이 들어간 시간과 팀을 적는 이상한 취미를 가지고 있다.

농구 경기는 정확히 48분동안 진행된다. 각 팀이 몇 분동안 이기고 있었는지 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 골이 들어간 횟수 N(1<=N<=100)이 주어진다. 둘째 줄부터 N개의 줄에 득점 정보가 주어진다. 득점 정보는 득점한 팀의 번호와 득점한 시간으로 이루어져 있다. 팀 번호는 1 또는 2이다. 득점한 시간은 MM:SS(분:초) 형식이며, 분과 초가 한자리 일 경우 첫째자리가 0이다. 분은 0보다 크거나 같고, 47보다 작거나 같으며, 초는 0보다 크거나 같고, 59보다 작거나 같다. 득점 시간이 겹치는 경우는 없다.

출력:

첫째 줄에 1번 팀이 이기고 있던 시간, 둘째 줄에 2번 팀이 이기고 있던 시간을 출력한다. 시간은 입력과 같은 형식(MM:SS)으로 출력한다.

풀이방법:

 1번팀과 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
= int(input())
timeline = []
for _ in range(N):
    timeline.append(input().split())
timeline = sorted(timeline, key=lambda x: x[1])
timeline.append([-1'48:00'])
one, two = 00
pivot = ''
one_ans, two_ans = 00
for team, time in timeline:
    if one==two:
        pass
    elif one>two:
        min_, sec = map(int,time.split(":"))
        min_p, sec_p = map(int, pivot.split(":"))
        one_ans += (min_*60+sec)-(min_p*60+sec_p)
    else:
        min_, sec = map(int,time.split(":"))
        min_p, sec_p = map(int, pivot.split(":"))
        two_ans += (min_*60+sec)-(min_p*60+sec_p)
    pivot = time
    if int(team)==1:
        one+=1
    elif int(team)==2:
        two+=1
q, r = divmod(one_ans, 60)
print(str(q).zfill(2)+":"+str(r).zfill(2))
q, r = divmod(two_ans, 60)
print(str(q).zfill(2)+":"+str(r).zfill(2))
cs

문제링크:

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

 

2852번: NBA 농구

첫째 줄에 골이 들어간 횟수 N(1<=N<=100)이 주어진다. 둘째 줄부터 N개의 줄에 득점 정보가 주어진다. 득점 정보는 득점한 팀의 번호와 득점한 시간으로 이루어져 있다. 팀 번호는 1 또는 2이다. 득

www.acmicpc.net

 

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

[BOJ]1189. 컴백홈  (0) 2022.08.04
[BOJ]12869.뮤탈리스크  (0) 2022.08.02
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]10709. 기상캐스터  (0) 2022.07.21
[BOJ]2870. 수학숙제  (0) 2022.07.19

문제:

알고리즘의 킹갓제너럴엠퍼러마제스티충무공알고리즘마스터 현우가 교수로 취임하였다!

그러나 학생들에게 크나큰 기대를 품고 첫 수업에 들어갔던 현우는 아무도 외판원 순회 문제(Traveling Salesman Problem, TSP)를 풀지 못하는 것을 보고 낙심하였다.

그 와중에 학생 남규는 TSP를 완전탐색으로 풀려고 하였고, 현우는 그걸 보고 경악을 금치 못한다. 왜냐면 TSP를 완전탐색으로 풀려면 O(N!)의 시간이 소모되는데, 이는 경악을 금치 못할 시간이기 때문이다.

그러나 남규는 O(N!)이 왜 큰지도 잘 모른다. 그래서 현우는 더더욱 경악을 금치 못하고, N!이 얼마나 큰지 대략적으로나마 알려주기 위해, 자연수 N이 주어지면 N!의 오른쪽 끝에 있는 0의 개수를 알려주기로 하였다.

그러나 현우는 경악을 금치 못하여 지금 코딩을 할 수 없는 상황이다. 여러분이 현우를 대신하여 프로그램을 작성하시오.

입력:

첫째 줄에 테스트 케이스의 개수 T가 주어지고, 이어서 T개의 줄에 정수 N이 주어진다(1 <= N <= 1000000000).

출력:

각 줄마다 N!의 오른쪽 끝에 있는 0의 개수를 출력한다.

풀이방법:

 오른쪽 끝에 0이 생기기 위해서는 2x5가 곱해져야 한다. 즉, N!을 소인수 분해 했을 때, 2와 5 중 더 작은 인수가 0의 갯수가 될 것이다. (2^P, 5^Q 일 때 P, Q 중 더 작은 수) 하지만 10까지만 봤을 때에도 2의 갯수가 압도적으로 많기 때문에 5의 개수만 알면 바로 0의 갯수를 알 수 있다. 따라서 5의 인수를 구하도록 한다.

1
2
3
4
5
6
7
8
9
10
= int(input())
for _ in range(T):
    n = int(input())
    five = 5
    ans = 0
    while five <= n:
        ans += n//five
        five *= 5
        
    print(ans)
cs

문제링크:

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

 

3474번: 교수가 된 현우

첫째 줄에 테스트 케이스의 개수 T가 주어지고, 이어서 T개의 줄에 정수 N이 주어진다(1 <= N <= 1000000000).

www.acmicpc.net

 

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

[BOJ]12869.뮤탈리스크  (0) 2022.08.02
[BOJ]2852. NBA 농구  (0) 2022.07.28
[BOJ]10709. 기상캐스터  (0) 2022.07.21
[BOJ]2870. 수학숙제  (0) 2022.07.19
[BOJ]11758. CCW  (0) 2022.07.14

문제:

JOI시는 남북방향이 H 킬로미터, 동서방향이 W 킬로미터인 직사각형 모양이다. JOI시는 가로와 세로의 길이가 1킬로미터인 H × W 개의 작은 구역들로 나뉘어 있다. 북쪽으로부터 i 번째, 서쪽으로부터 j 번째에 있는 구역을 (i, j) 로 표시한다.

각 구역의 하늘에는 구름이 있을 수도, 없을 수도 있다. 모든 구름은 1분이 지날 때마다 1킬로미터씩 동쪽으로 이동한다. 오늘은 날씨가 정말 좋기 때문에 JOI시의 외부에서 구름이 이동해 오는 경우는 없다.

지금 각 구역의 하늘에 구름이 있는지 없는지를 알고 있다. 기상청에서 일하고 있는 여러분은 각 구역에 대해서 지금부터 몇 분뒤 처음으로 하늘에 구름이 오는지를 예측하는 일을 맡았다.

각 구역에 대해서 지금부터 몇 분뒤 처음으로 하늘에 구름이 오는지를 구하여라.

입력:

입력은 1 + H 행으로 주어진다.

첫 번째 행에는 정수 H, W (1 ≦ H ≦ 100, 1 ≦ W ≦ 100) 가 공백을 사이에 주고 주어진다. 이것은 JOI시가 H × W 개의 작은 구역으로 나뉘어 있다는 것을 의미한다.

이어진 H 개의 행의 i번째 행 (1 ≦ i ≦ H) 에는 W문자의 문자열이 주어진다. W 개의 문자 중 j번째 문자 (1 ≦ j ≦ W) 는, 구역 (i, j) 에 지금 구름이 떠 있는지 아닌지를 나타낸다. 구름이 있는 경우에는 영어 소문자 'c' 가, 구름이 없는 경우에는 문자 '.' 가 주어진다.

출력:

출력은 H 행으로, 각 행에는 공백으로 구분된 W 개의 정수를 출력한다. 출력의 i 번째 행 j 번째 정수 (1 ≦ i ≦ H, 1 ≦ j ≦ W) 는, 지금부터 몇 분후에 처음으로 구역 (i, j) 에 구름이 뜨는지를 표시한다. 단, 처음부터 구역 (i, j) 에 구름이 떠 있었던 경우에는 0을, 몇 분이 지나도 구름이 뜨지 않을 경우에는 -1을 출력한다.

풀이방법:

주어진 조건대로 구현해야 하는 문제다. 이 문제에서는 총 3가지 행동을 수행한다.

1. 지금 하늘에 구름(c)가 있는가?

2. 구름이 몇 분뒤에 지금 하늘에 도착하는가?

3. 구름의 이동

따라서 while 계속해서 반복하고, 1에 의해서 break 조건을 만든다. 그 동안에 2와 3을 반복하며 answer 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
from collections import deque
 
def check_sky(sky):
    for i in range(H):
        for j in range(W):
            if sky[i][j]=='c':
                return 1
    return 0
 
def update_sky(sky, count):
    for i in range(H):
        for j in range(W):
            if sky[i][j]=='c':
                if answer[i][j]==-1:
                    answer[i][j] = count
 
H, W = map(int,input().split())
answer = [ [-1 for _ in range(W)] for _ in range(H)]
 
sky = []
for _ in range(H):
    sky.append(deque(input()))
    
count = 0
while True:
    if not check_sky(sky):
        break
    update_sky(sky, count)
    for i in range(H):
        sky[i].pop()
        sky[i].appendleft('.')
    count+=1
for ans in answer:
    print(*ans)
cs

문제링크:

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

 

10709번: 기상캐스터

출력은 H 행으로, 각 행에는 공백으로 구분된 W 개의 정수를 출력한다. 출력의 i 번째 행 j 번째 정수 (1 ≦ i ≦ H, 1 ≦ j ≦ W) 는, 지금부터 몇 분후에 처음으로 구역 (i, j) 에 구름이 뜨는지를 표시

www.acmicpc.net

 

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

[BOJ]2852. NBA 농구  (0) 2022.07.28
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]2870. 수학숙제  (0) 2022.07.19
[BOJ]11758. CCW  (0) 2022.07.14
[BOJ]4659. 비밀번호 발음하기  (0) 2022.07.12

+ Recent posts