문제:

찬솔이는 블로그를 시작한 지 벌써 일이 지났다.

요즘 바빠서 관리를 못 했다가 방문 기록을 봤더니 벌써 누적 방문 수가 6만을 넘었다.

 

찬솔이는 일 동안 가장 많이 들어온 방문자 수와 그 기간들을 알고 싶다.

찬솔이를 대신해서 일 동안 가장 많이 들어온 방문자 수와 기간이 몇 개 있는지 구해주자.

입력:

첫째 줄에 블로그를 시작하고 지난 일수 가 공백으로 구분되어 주어진다.

둘째 줄에는 블로그 시작 일차부터 일차까지 하루 방문자 수가 공백으로 구분되어 주어진다.

출력:

첫째 줄에 일 동안 가장 많이 들어온 방문자 수를 출력한다. 만약 최대 방문자 수가 0명이라면 SAD를 출력한다.

만약 최대 방문자 수가 0명이 아닌 경우 둘째 줄에 기간이 몇 개 있는지 출력한다.

풀이방법:

X만큼의 구간을 슬라이딩 하면서 최댓값을 갱신하고, 최댓값이랑 같은 경우에는 기간을 증가시켜준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
N, X = map(int, input().split())
visit = list(map(int, input().split()))
 
total = sum(visit[:X])
answer = total
count = 1
for i in range(X, N):
    total+=visit[i]
    total-=visit[i-X]
    if total > answer:
        count = 1
        answer = total
    elif total == answer:
        count += 1
 
if answer!=0:
    print(answer)
    print(count)
else:
    print("SAD")
cs

문제링크:

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

 

21921번: 블로그

첫째 줄에 $X$일 동안 가장 많이 들어온 방문자 수를 출력한다. 만약 최대 방문자 수가 0명이라면 SAD를 출력한다. 만약 최대 방문자 수가 0명이 아닌 경우 둘째 줄에 기간이 몇 개 있는지 출력한다

www.acmicpc.net

 

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

[BOJ] 20920. 영단어 암기는 괴로워  (0) 2023.07.19
[Programmers] Lv 2. 연속된 부분 수열의 합  (0) 2023.07.18
[Programmers] Lv 2. 롤케이크 자르기  (0) 2023.07.14
[BOJ] 1111. IQ Test  (0) 2023.07.13
[BOJ] 2002. 추월  (0) 2023.07.12

문제:

풀이방법:

우선 한쪽으로 케이크의 모든 토핑을 모아두고, 하나씩 반대로 옮기면서 갯수가 같아지는 지점을 체크하도록 한다.

 이 과정을 편하게 하기 위해 dict 자료형을 선택했고, collections의 defaultdict을 사용했다. defaultdict은 dict의 key 초기화 과정이 필요하지 않다는 장점이 존재한다.

 따라서 하나씩 토핑을 제거하고, 제거한 토핑은 반대 dict의 넘겨준다. 만약 value가 0이 된다면 key를 제거한다. 이렇게 했을 때, 두 dict의 key의 길이가 같다면 공평하게 자르는 방법이라고 생각한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from collections import defaultdict
def solution(topping):
    answer = 0
    cake = defaultdict(int)
    for t in topping:
        cake[t]+=1
 
    split_cake = defaultdict(int)
    for t in topping:
        cake[t]-=1
        split_cake[t]+=1
        if cake[t]==0:
            del cake[t]
        if len(cake.keys()) == len(split_cake.keys()):
            answer+=1
 
    return answer
cs

문제링크:

https://school.programmers.co.kr/learn/courses/30/lessons/132265

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

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

[Programmers] Lv 2. 연속된 부분 수열의 합  (0) 2023.07.18
[BOJ] 21921. 블로그  (0) 2023.07.17
[BOJ] 1111. IQ Test  (0) 2023.07.13
[BOJ] 2002. 추월  (0) 2023.07.12
[Programmers]Lv 2. 숫자 변환하기  (0) 2023.07.11

문제:

대한민국을 비롯한 대부분의 나라에서는 터널 내에서의 차선 변경을 법률로 금하고 있다. 조금만 관찰력이 있는 학생이라면 터널 내부에서는 차선이 파선이 아닌 실선으로 되어 있다는 것을 알고 있을 것이다. 이는 차선을 변경할 수 없음을 말하는 것이고, 따라서 터널 내부에서의 추월은 불가능하다.

소문난 명콤비 경찰 대근이와 영식이가 추월하는 차량을 잡기 위해 한 터널에 투입되었다. 대근이는 터널의 입구에, 영식이는 터널의 출구에 각각 잠복하고, 대근이는 차가 터널에 들어가는 순서대로, 영식이는 차가 터널에서 나오는 순서대로 각각 차량 번호를 적어 두었다.

N개의 차량이 지나간 후, 대근이와 영식이는 자신들이 적어 둔 차량 번호의 목록을 보고, 터널 내부에서 반드시 추월을 했을 것으로 여겨지는 차들이 몇 대 있다는 것을 알게 되었다. 대근이와 영식이를 도와 이를 구하는 프로그램을 작성해 보자.

입력:

입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이가 적은 차량 번호 목록이 주어진다. 각 차량 번호는 6글자 이상 8글자 이하의 문자열로, 영어 대문자('A'-'Z')와 숫자('0'-'9')로만 이루어져 있다.

같은 차량 번호가 두 번 이상 주어지는 경우는 없다.

출력:

첫째 줄에 터널 내부에서 반드시 추월을 했을 것으로 여겨지는 차가 몇 대인지 출력한다.

풀이방법:

먼저 들어간 차량부터 1이라고 라벨링을 할 때, 추월한 차량의 뒤 차량들 중에는 본인 차의 숫자보다 작은 숫자가 반드시 존재하게 된다. 따라서 이러한 경우를 추월한 차량이라고 생각하고 갯수를 세도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
= int(input())
 
in_car = {}
for i in range(1, N+1):
    number = input()
    in_car[number] = i
 
order = []
for j in range(1, N+1):
    out = input()
    order.append(in_car[out])
 
answer = 0
for i in range(N):
    for j in range(i+1, N):
        if order[i] > order[j]:
            answer+=1
            break
 
print(answer)
cs

문제링크:

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

 

2002번: 추월

입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이

www.acmicpc.net

 

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

[Programmers] Lv 2. 롤케이크 자르기  (0) 2023.07.14
[BOJ] 1111. IQ Test  (0) 2023.07.13
[Programmers]Lv 2. 숫자 변환하기  (0) 2023.07.11
[BOJ] 2623. 음악프로그램  (0) 2023.07.10
[BOJ] 1343. 폴리오미노  (0) 2023.07.07

문제:

풀이방법:

y를 만드는 것이 목적이므로 y 길이를 가지고 있는 DP 배열을 만들어서 연산을 수행하도록 한다.

DP에 연산을 하면서 연산 횟수를 채워나가면 되는데, 최소 연산 횟수를 구해야 하므로 min 연산을 추가로 하도록 한다. 즉, 특정 숫자 x에 접근할 수 있는 방법은 여러가지가 있을텐데 그 중 가장 작은 횟수만 선택하는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def solution(x, y, n):
    dp = [float('inf')]*(y+1)
    dp[x] = 0
 
    for i in range(x, y+1):
        if dp[i] == float('inf'):
            continue
 
        if i+n<=y:
            dp[i+n] = min(dp[i+n], dp[i]+1)
 
        if 2*i<=y:
            dp[2*i] = min(dp[2*i], dp[i]+1)
 
        if 3*i<=y:
            dp[3*i] = min(dp[3*i], dp[i]+1)
    if dp[y] == float('inf'):
        return -1
    return dp[y]
cs

문제링크:

https://school.programmers.co.kr/learn/courses/30/lessons/154538

 

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

[BOJ] 1111. IQ Test  (0) 2023.07.13
[BOJ] 2002. 추월  (0) 2023.07.12
[BOJ] 2623. 음악프로그램  (0) 2023.07.10
[BOJ] 1343. 폴리오미노  (0) 2023.07.07
[BOJ] 18405. 경쟁적 전염  (0) 2023.07.06

문제:

인터넷 방송 KOI(Korea Open Internet)의 음악 프로그램 PD인 남일이는 자기가 맡은 프로그램 '뮤직 KOI'에서 가수의 출연 순서를 정하는 일을 매우 골치 아파한다. 순서를 정하기 위해서는 많은 조건을 따져야 한다.

그래서 오늘 출연 예정인 여섯 팀의 가수에 대해서 남일이가 보조 PD 세 명에게 각자 담당한 가수의 출연 순서를 정해오게 하였다. 보조 PD들이 가져온 것은 아래와 같다.

  • 1 4 3
  • 6 2 5 4
  • 2 3

첫 번째 보조 PD는 1번 가수가 먼저, 다음에 4번 가수, 다음에 3번 가수가 출연하기로 순서를 정했다. 두 번째 보조 PD는 6번, 2번, 5번, 4번 순으로 자기 담당 가수들의 순서를 정했다. 한 가수를 여러 보조 PD가 담당할 수도 있다. 마지막으로, 세 번째 보조 PD는 2번 먼저, 다음에 3번으로 정했다.

남일이가 할 일은 이 순서들을 모아서 전체 가수의 순서를 정하는 것이다. 남일이는 잠시 생각을 하더니 6 2 1 5 4 3으로 순서를 정했다. 이렇게 가수 순서를 정하면 세 보조 PD가 정해온 순서를 모두 만족한다. 물론, 1 6 2 5 4 3으로 전체 순서를 정해도 괜찮다.

경우에 따라서 남일이가 모두를 만족하는 순서를 정하는 것이 불가능할 수도 있다. 예를 들어, 세 번째 보조 PD가 순서를 2 3 대신에 3 2로 정해오면 남일이가 전체 순서를 정하는 것이 불가능하다. 이번에 남일이는 우리 나라의 월드컵 4강 진출 기념 음악제의 PD를 맡게 되었는데, 출연 가수가 아주 많다. 이제 여러분이 해야 할 일은 보조 PD들이 가져 온 순서들을 보고 남일이가 가수 출연 순서를 정할 수 있도록 도와 주는 일이다.

보조 PD들이 만든 순서들이 입력으로 주어질 때, 전체 가수의 순서를 정하는 프로그램을 작성하시오.

입력:

첫째 줄에는 가수의 수 N과 보조 PD의 수 M이 주어진다. 가수는 번호 1, 2,…,N 으로 표시한다. 둘째 줄부터 각 보조 PD가 정한 순서들이 한 줄에 하나씩 나온다. 각 줄의 맨 앞에는 보조 PD가 담당한 가수의 수가 나오고, 그 뒤로는 그 가수들의 순서가 나온다. N은 1이상 1,000이하의 정수이고, M은 1이상 100이하의 정수이다.

출력:

출력은 N 개의 줄로 이뤄지며, 한 줄에 하나의 번호를 출력한 다. 이들은 남일이가 정한 가수들의 출연 순서를 나타낸다. 답이 여럿일 경우에는 아무거나 하나를 출력 한다. 만약 남일이가 순서를 정하는 것이 불가능할 경우에는 첫째 줄에 0을 출력한다.

풀이방법:

 순서가 정해져있는 작업을 차례로 수행해야 할 때 순서를 결정해주는 문제이므로 '위상 정렬'을 사용해야 한다. 위상 정렬에 대한 설명은 다음 페이지에 설명이 잘 되어 있기에 링크를 달아두도록 한다.

https://m.blog.naver.com/ndb796/221236874984

 

25. 위상 정렬(Topology Sort)

  위상 정렬(Topology Sort)은 '순서가 정해져있는 작업'을 차례로 수행해야 할 때 그 순서를 ...

blog.naver.com

 문제의 설명에서 '세 번째 보조 PD가 순서를 2 3 대신에 3 2로 정해오면 남일이가 전체 순서를 정하는 것이 불가능하다.' 라는 것이 있는데, 이는 위상 정렬을 수행할 때 사이클이 생기는 경우에 해당한다. 이러한 경우에 위상정렬을 하면서 순서를 정할 때, N명이 모두 순서가 정해지지 않게 된다.

 따라서 위상정렬을 하고 난 뒤에 길이가 N이 아니라면 -1을 출력하도록 한다.

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
from collections import deque
 
N, M = map(int, input().split())
 
orders = [[] for _ in range(1+N)]
indegree = [0* (1+N)
for i in range(M):
    order = list(map(int, input().split()))
    for i in range(1len(order)-1):
        orders[order[i]].append(order[i+1])
        indegree[order[i+1]] += 1
 
 
def topology_sort():
    results = []
    queue = deque()
    for i in range(1, N+1):
        if indegree[i] == 0:
            queue.append(i)
 
    while queue:
        now = queue.popleft()
        results.append(now)
        for i in orders[now]:
            indegree[i] -= 1
            if indegree[i] == 0:
                queue.append(i)
    
    return results
 
answers = topology_sort()
if len(answers)!=N:
    print(0)
else:
    for ans in answers:
        print(ans)
cs

 

문제링크:

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

 

2623번: 음악프로그램

첫째 줄에는 가수의 수 N과 보조 PD의 수 M이 주어진다. 가수는 번호 1, 2,…,N 으로 표시한다. 둘째 줄부터 각 보조 PD가 정한 순서들이 한 줄에 하나씩 나온다. 각 줄의 맨 앞에는 보조 PD가 담당한

www.acmicpc.net

 

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

[BOJ] 2002. 추월  (0) 2023.07.12
[Programmers]Lv 2. 숫자 변환하기  (0) 2023.07.11
[BOJ] 1343. 폴리오미노  (0) 2023.07.07
[BOJ] 18405. 경쟁적 전염  (0) 2023.07.06
[Programmers]Lv 2. 택배상자  (0) 2023.07.05

문제:

NxN 크기의 시험관이 있다. 시험관은 1x1 크기의 칸으로 나누어지며, 특정한 위치에는 바이러스가 존재할 수 있다. 모든 바이러스는 1번부터 K번까지의 바이러스 종류 중 하나에 속한다.

시험관에 존재하는 모든 바이러스는 1초마다 상, 하, 좌, 우의 방향으로 증식해 나간다. 단, 매 초마다 번호가 낮은 종류의 바이러스부터 먼저 증식한다. 또한 증식 과정에서 특정한 칸에 이미 어떠한 바이러스가 존재한다면, 그 곳에는 다른 바이러스가 들어갈 수 없다.

시험관의 크기와 바이러스의 위치 정보가 주어졌을 때, S초가 지난 후에 (X,Y)에 존재하는 바이러스의 종류를 출력하는 프로그램을 작성하시오. 만약 S초가 지난 후에 해당 위치에 바이러스가 존재하지 않는다면, 0을 출력한다. 이 때 X와 Y는 각각 행과 열의 위치를 의미하며, 시험관의 가장 왼쪽 위에 해당하는 곳은 (1,1)에 해당한다.

예를 들어 다음과 같이 3x3 크기의 시험관이 있다고 하자. 서로 다른 1번, 2번, 3번 바이러스가 각각 (1,1), (1,3), (3,1)에 위치해 있다. 이 때 2초가 지난 뒤에 (3,2)에 존재하는 바이러스의 종류를 계산해보자.

1초가 지난 후에 시험관의 상태는 다음과 같다.

 

2초가 지난 후에 시험관의 상태는 다음과 같다.

결과적으로 2초가 지난 뒤에 (3,2)에 존재하는 바이러스의 종류는 3번 바이러스다. 따라서 3을 출력하면 정답이다.

입력:

첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치에 존재하는 바이러스의 번호가 공백을 기준으로 구분되어 주어진다. 단, 해당 위치에 바이러스가 존재하지 않는 경우 0이 주어진다. 또한 모든 바이러스의 번호는 K이하의 자연수로만 주어진다. N+2번째 줄에는 S, X, Y가 공백을 기준으로 구분되어 주어진다. (0 ≤ S ≤ 10,000, 1 ≤ X, Y  N)

출력:

S초 뒤에 (X,Y)에 존재하는 바이러스의 종류를 출력한다. 만약 S초 뒤에 해당 위치에 바이러스가 존재하지 않는다면, 0을 출력한다.

풀이방법:

 바이러스 번호가 낮은 것부터 2차원 배열에 확산시키는 문제로 너비 우선 탐색에 해당한다. 처음에는 시간을 고려하지 않고, 너비 우선 탐색만 생각하고 문제를 풀려고 했으나 계속해서 시간초과가 발생하게 되었다.

 처음 생각했던 방법은 중복으로 탐색하는 경우도 많았으며, 이미 다 채워져 있었는데 시간(S)이 남았다는 이유로 계속 2차원 배열 탐색을 계속했기 때문에 시간초과가 발생했던 것으로 보인다. 

 그래서 deque에 바이러스 종류, 시간, 좌표등을 모두 저장하고 이를 기준으로 바이러스를 증식시키는 것으로 수정하게 되었다. 초기 시험관을 받고 바이러스 정보를 모두 deque에 넣고 정렬하면 낮은 종류의 바이러스부터 먼저 증식시킬 수 있다.

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
from collections import deque
 
N, K = map(int,input().split())
 
virus = []
virus_pos = []
for i in range(N):
    row = list(map(int,input().split()))
    virus.append(row)
    for j in range(N):
        if row[j]!=0:
            virus_pos.append((row[j], 0, i, j))
 
s, x, y = map(int, input().split())
queue = deque(sorted(virus_pos))
 
dx = [00-11]
dy = [1-100]
while queue:
    v, t, a, b = queue.popleft()
    if t == s:
        break
    for d in range(4):
        nx = a + dx[d]
        ny = b + dy[d]
        if 0<= nx < N and 0<= ny < N and virus[nx][ny] == 0:
            virus[nx][ny] = v
            queue.append((v, t+1,nx, ny))
print(virus[x-1][y-1])
cs

 

문제링크:

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

 

18405번: 경쟁적 전염

첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치

www.acmicpc.net

 

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

[BOJ] 2623. 음악프로그램  (0) 2023.07.10
[BOJ] 1343. 폴리오미노  (0) 2023.07.07
[Programmers]Lv 2. 택배상자  (0) 2023.07.05
[1138] 한 줄로 서기  (0) 2023.07.04
[2477] 참외밭  (0) 2023.07.03

문제:

풀이방법:

처음에 문제를 이해하는 것이 가장 어려웠던 것 같다. 다음과 같은 흐름으로 문제를 이해하면 도움이 될 것 같다.

 

  • 택배 상자는 무조건 [1,2,3,4, ... ] 와 같은 순서로 주어진다.
    • 택배 기사님의 순서와는 무관하다.
  • 문제의 설명을 보면 Stack을 사용해야 한다. 이 때, 컨테이너 벨트(main), 보조 컨테이너 벨트(sub) 모두 stack으로 이루어진 배열이다.
    • 단, 컨테이너 벨트에는 [1,2,3,4, ...]가 이미 적재되어 있다.
  • main에서 sub로 이동하는 것은 가능하지만, sub에서 main으로 이동하는 것은 불가능하다.

결국 2개의 stack 배열을 사용해서 택배 기사님의 순서를 맞추는 문제라고 생각하면 된다.

 

 main에서 sub로만 이동하는 것이 가능하기 때문에 main 혹은 sub의 out 상자가 첫 택배 기사님의 순서에 맞게 세팅을 해둔다. 택배 기사님이 원하는 택배 상자를 적재 하고 main이나 sub에 또 원하는 상자가 있다면 연속해서 적재하며 만약 그렇지 않다면 main에서 sub로 이동시키며 조건을 만족하는지 계속해서 확인한다.

 이 과정을 main의 모든 택배 상자가 비었으며, 더 이상 적재하지 못할 때까지 반복한다.

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
def solution(order):
    main = list(range(len(order), 0-1))
    sub = []
    answer = []
    while True:
        if main[-1]==order[0]:
            break
        elif len(sub) and sub[-1]==order[0]:
            break
        sub.append(main.pop())
        
    idx = 0
    while True:
        if len(main) and (main[-1== order[idx]):
            answer.append(main.pop())
            idx += 1
        elif len(sub) and (sub[-1== order[idx]):
            answer.append(sub.pop())
            idx += 1
        else:
            if len(main):
                sub.append(main.pop())
            else:
                break
    return len(answer)
cs

문제링크:

https://school.programmers.co.kr/learn/courses/30/lessons/131704

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

[BOJ] 1343. 폴리오미노  (0) 2023.07.07
[BOJ] 18405. 경쟁적 전염  (0) 2023.07.06
[1138] 한 줄로 서기  (0) 2023.07.04
[2477] 참외밭  (0) 2023.07.03
[BOJ]14620. 꽃길  (1) 2022.08.18

문제:

시골에 있는 태양이의 삼촌 댁에는 커다란 참외밭이 있다. 문득 태양이는 이 밭에서 자라는 참외가 도대체 몇 개나 되는지 궁금해졌다. 어떻게 알아낼 수 있는지 골똘히 생각하다가 드디어 좋은 아이디어가 떠올랐다. 유레카! 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

+ Recent posts