#20056 마법사 상어와 파이어볼 (골드5)

유형 : 시뮬레이션 문제

point 1. deque를 이용해 파이어볼 빼주기

point 2. 파이어볼을 바로 이동시키면 이동시킨 파이어볼을 또 이동시킬 수 있다. temp에 이동시킬 값을 저장해두고 이동을 마치면 array에 더해주기

 

문제

어른 상어가 마법사가 되었고, 파이어볼을 배웠다.

마법사 상어가 크기가 N×N인 격자에 파이어볼 M개를 발사했다. 가장 처음에 파이어볼은 각자 위치에서 이동을 대기하고 있다. i번 파이어볼의 위치는 (ri, ci), 질량은 mi이고, 방향은 di, 속력은 si이다. 위치 (r, c)는 r행 c열을 의미한다.

격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.

파이어볼의 방향은 어떤 칸과 인접한 8개의 칸의 방향을 의미하며, 정수로는 다음과 같다.

7 0 1
6   2
5 4 3

마법사 상어가 모든 파이어볼에게 이동을 명령하면 다음이 일들이 일어난다.

  1. 모든 파이어볼이 자신의 방향 di로 속력 si칸 만큼 이동한다.
    • 이동하는 중에는 같은 칸에 여러 개의 파이어볼이 있을 수도 있다.
  2. 이동이 모두 끝난 뒤, 2개 이상의 파이어볼이 있는 칸에서는 다음과 같은 일이 일어난다.
    1. 같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.
    2. 파이어볼은 4개의 파이어볼로 나누어진다.
    3. 나누어진 파이어볼의 질량, 속력, 방향은 다음과 같다.
      1. 질량은 ⌊(합쳐진 파이어볼 질량의 합)/5⌋이다.
      2. 속력은 ⌊(합쳐진 파이어볼 속력의 합)/(합쳐진 파이어볼의 개수)⌋이다.
      3. 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수이면, 방향은 0, 2, 4, 6이 되고, 그렇지 않으면 1, 3, 5, 7이 된다.
    4. 질량이 0인 파이어볼은 소멸되어 없어진다.

마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 구해보자.

입력

첫째 줄에 N, M, K가 주어진다.

둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다.

서로 다른 두 파이어볼의 위치가 같은 경우는 입력으로 주어지지 않는다.

출력

마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 출력한다.

 

from collections import deque
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]

# 파이어볼 좌표 반환
def find_fire(array):
    position = []
    for i in range(n):
        for j in range(n):
            if len(array[i][j]) != 0:
                position.append([i,j])
    return position

# 파이어볼 이동
def move_fire():
    global array
    position = find_fire(array)
    temp = []
    for x,y in position:
        for _ in range(len(array[x][y])):
            m, s, d = array[x][y].popleft()
            nx, ny = (x+dx[d]*s)%n, (y+dy[d]*s)%n
            temp.append([nx, ny, m,s,d])
    for r, c, m, s, d in temp:
        array[r][c].append([m, s, d])
    # print(array)

#파이어볼 합치기
def sum_fire():
    global array
    position = find_fire(array)
    d_list = []
    temp = []
    for x,y in position:
        sum_m, sum_s, count, even_d, odd_d = 0, 0, 0, False, False

        if len(array[x][y]) > 1:
            for _ in range(len(array[x][y])):
                m, s, d = array[x][y].popleft()
                sum_m += m
                sum_s += s
                count += 1
                if d%2 == 0:
                    even_d = True
                else:
                    odd_d = True
            r_m = int(sum_m/5)
            r_s = int(sum_s/count)

            if r_m != 0: # 질량이 0이 아닐때
                if even_d == True and odd_d == True: #홀짝 섞여있음
                    d_list = [1,3,5,7]
                else: # 모두 홀수 or 모두 짝수
                    d_list = [0,2,4,6]

                # 4방향으로 나누어진다
                for i in d_list:
                    temp.append([x, y, r_m, r_s, i])

    for r, c, m, s, d in temp:
        array[r][c].append([m, s, d])
    # print(array)

# n : 맵 크기, m : 파이어볼 개수, k : 명령횟수
n,m,k = map(int, input().split())
array = [[deque() for _ in range(n)] for _ in range(n)]
answer = 0
# r : 행, c : 열, m : 질량, s : 속력, d : 방향
for i in range(m):
    r, c, m, s, d = map(int, input().split())
    array[r - 1][c - 1].append([m, s, d])

for i in range(k):
    move_fire()
    sum_fire()

position = find_fire(array)
for x, y in position:
    for _ in range(len(array[x][y])):
        m, s, d = array[x][y].popleft()
        answer += m
print(answer)
반응형

# 19236 청소년 상어 (골드2)

유형 : DFS, 시뮬레이션

문제

아기 상어가 성장해 청소년 상어가 되었다.

4×4크기의 공간이 있고, 크기가 1×1인 정사각형 칸으로 나누어져 있다. 공간의 각 칸은 (x, y)와 같이 표현하며, x는 행의 번호, y는 열의 번호이다. 한 칸에는 물고기가 한 마리 존재한다. 각 물고기는 번호와 방향을 가지고 있다. 번호는 1보다 크거나 같고, 16보다 작거나 같은 자연수이며, 두 물고기가 같은 번호를 갖는 경우는 없다. 방향은 8가지 방향(상하좌우, 대각선) 중 하나이다.

오늘은 청소년 상어가 이 공간에 들어가 물고기를 먹으려고 한다. 청소년 상어는 (0, 0)에 있는 물고기를 먹고, (0, 0)에 들어가게 된다. 상어의 방향은 (0, 0)에 있던 물고기의 방향과 같다. 이후 물고기가 이동한다.

물고기는 번호가 작은 물고기부터 순서대로 이동한다. 물고기는 한 칸을 이동할 수 있고, 이동할 수 있는 칸은 빈 칸과 다른 물고기가 있는 칸, 이동할 수 없는 칸은 상어가 있거나, 공간의 경계를 넘는 칸이다. 각 물고기는 방향이 이동할 수 있는 칸을 향할 때까지 방향을 45도 반시계 회전시킨다. 만약, 이동할 수 있는 칸이 없으면 이동을 하지 않는다. 그 외의 경우에는 그 칸으로 이동을 한다. 물고기가 다른 물고기가 있는 칸으로 이동할 때는 서로의 위치를 바꾸는 방식으로 이동한다.

물고기의 이동이 모두 끝나면 상어가 이동한다. 상어는 방향에 있는 칸으로 이동할 수 있는데, 한 번에 여러 개의 칸을 이동할 수 있다. 상어가 물고기가 있는 칸으로 이동했다면, 그 칸에 있는 물고기를 먹고, 그 물고기의 방향을 가지게 된다. 이동하는 중에 지나가는 칸에 있는 물고기는 먹지 않는다. 물고기가 없는 칸으로는 이동할 수 없다. 상어가 이동할 수 있는 칸이 없으면 공간에서 벗어나 집으로 간다. 상어가 이동한 후에는 다시 물고기가 이동하며, 이후 이 과정이 계속해서 반복된다.

입력

첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는 8보다 작거나 같은 자연수를 의미하고, 1부터 순서대로 ↑, ↖, ←, ↙, ↓, ↘, →, ↗ 를 의미한다.

출력

상어가 먹을 수 있는 물고기 번호의 합의 최댓값을 출력한다.

 

import copy

dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, -1, -1, -1, 0, 1, 1, 1]

# 상어 이동 후보지 반환
def shark_move(array, x,y):
    positions = []
    direction = array[x][y][1] # 상어 방향
    for i in range(1, 4):
        nx, ny = x + dx[direction], y + dy[direction]
        # 경계값 안에 있고, 물고기가 있으면 움직일 수 있다
        if 0 <= nx < 4 and 0 <= ny < 4 and 1 <= array[nx][ny][0] <= 16:
            positions.append([nx, ny])
        x, y = nx, ny
    return positions

# 물고기 위치 찾기
def find_fish(array, index): # 배열, 물고기 번호
    for i in range(4):
        for j in range(4):
            if array[i][j][0] == index:
                return (i, j)
    # 물고기가 없는 경우
    return None

# 물고기 이동
def move_fish(array, now_x, now_y): # 배열, 상어좌표 x, y
    position = []
    for i in range(1,17):
        position = find_fish(array,i) # 물고기 좌표 찾기
        if position is None: # 빈칸인 경우
            continue
        x,y = position[0], position[1]
        dir = array[x][y][1] # 물고기 방향
        for i in range(8):
            nx,ny = x+dx[dir], y+dy[dir]
            if 0 <= nx < 4 and 0<=ny<4: # 경계값 안에 있는 경우
                if not (nx == now_x and ny == now_y): # 상어가 있는 칸이 아닌 경우
                    # 물고기 이동(값 변경)
                    array[x][y][0], array[nx][ny][0] = array[nx][ny][0], array[x][y][0]
                    array[x][y][1], array[nx][ny][1] = array[nx][ny][1], dir
                    break
            # 상어가 있거나, 경계값에 있다면 45도 반시계 방향으로 돌리기
            dir = (dir +1)%8


def dfs(array, x, y, total):
    global answer
    array = copy.deepcopy(array)

    # 해당 위치 물고기 먹기
    number = array[x][y][0]
    array[x][y][0] = -1

    # 물고기 이동
    move_fish(array, x, y)

    # 상어 이동할 수 있는 후보 확인
    result = shark_move(array, x, y)

    # 해당 먹이 먹는 모든 과정 탐색
    answer = max(answer, total + number)
    for next_x, next_y in result:
        dfs(array, next_x, next_y, total + number)


temp = [list(map(int, input().split())) for _ in range(4)]
array = [[None]*4 for _ in range(4)]
for i in range(4):
    for j in range(4):
        # array(x좌표, y좌표) : [물고기 번호, 방향 번호(0~7로변경)]
        array[i][j] = [temp[i][j*2], temp[i][j*2+1]-1]
# print(array)
answer = 0
dfs(array, 0, 0, 0) #(0,0) 상어 출발
print(answer)
반응형

유형별 문제 풀이 - 기본 자료구조 - 02. 핵심 유형 문제풀이

# 1874 스택 수열 (실버3)

-> 문제 유형 : 스택, 그리디

스택 (stack)은 기본적인 자료구조 중 하나로, 컴퓨터 프로그램을 작성할 때 자주 이용되는 개념이다. 스택은 자료를 넣는 (push) 입구와 자료를 뽑는 (pop) 입구가 같아 제일 나중에 들어간 자료가 제일 먼저 나오는 (LIFO, Last in First out) 특성을 가지고 있다.

1부터 n까지의 수를 스택에 넣었다가 뽑아 늘어놓음으로써, 하나의 수열을 만들 수 있다. 이때, 스택에 push하는 순서는 반드시 오름차순을 지키도록 한다고 하자. 임의의 수열이 주어졌을 때 스택을 이용해 그 수열을 만들 수 있는지 없는지, 있다면 어떤 순서로 push와 pop 연산을 수행해야 하는지를 알아낼 수 있다. 이를 계산하는 프로그램을 작성하라.

ex)
n = 8
data = 4, 3, 6, 8, 7, 5, 2, 1

result = + + + + - - + + - + + - - - - -
stack  = 1 2 3 4  4 3 5 6 6 7 8 8 7 5 2 1 
n = int(input())

count = 1
stack = []
result = []

for i in range(n): # 데이터 개수만큼 반복
    data = int(input())
    while count <= data: # 입력받은 데이터에 도달할 때까지 삽입
        stack.append(count)
        result.append('+')
        count+=1
    if stack[-1] == data: # 스택의 최상위 원소가 데이터와 같을 때 
        stack.pop()
        result.append('-')
    else: # 불가능한 경우
        print('NO')
        exit(0)
        
print('\n'.join(result)) # 가능한 경우

 

# 1966 프린터 큐 (실버 3)

-> 문제 유형 : 큐, 구현, 그리디

여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 Queue 자료구조에 쌓여서 FIFO - First In First Out - 에 따라 인쇄가 되게 된다. 하지만 상근이는 새로운 프린터기 내부 소프트웨어를 개발하였는데, 이 프린터기는 다음과 같은 조건에 따라 인쇄를 하게 된다.

  1. 현재 Queue의 가장 앞에 있는 문서의 ‘중요도’를 확인한다.
  2. 나머지 문서들 중 현재 문서보다 중요도가 높은 문서가 하나라도 있다면, 이 문서를 인쇄하지 않고 Queue의 가장 뒤에 재배치 한다. 그렇지 않다면 바로 인쇄를 한다.

예를 들어 Queue에 4개의 문서(A B C D)가 있고, 중요도가 2 1 4 3 라면 C를 인쇄하고, 다음으로 D를 인쇄하고 A, B를 인쇄하게 된다.

여러분이 할 일은, 현재 Queue에 있는 문서의 수와 중요도가 주어졌을 때, 어떤 한 문서가 몇 번째로 인쇄되는지 알아내는 것이다. 예를 들어 위의 예에서 C문서는 1번째로, A문서는 3번째로 인쇄되게 된다.

tc = int(input()) # 테스트케이스 개수

for i in range(tc):
    n,m = list(map(int, input().split())) # n : 문서의 개수, m : 확인하고 싶은 문서
    queue = []
    for index, i in enumerate(list(map(int, input().split()))):
        queue.append((index, i)) # (문서의 index, 중요도) 저장
    count = 0 # 인쇄한 문서 갯수

    while True:
        if queue[0][1] == max(queue, key=lambda x :x[1])[1] : # 맨앞의 문서가 현재 리스트중 중요도가 가장 높다면
            count += 1
            if queue[0][0] == m: # 그것이 확인하고 싶은 문서라면 출력
                print(count)
                break
            else: # 아니라면 갯수만 추가하고 pop 해준다
                queue.pop(0)
        else:   # 맨앞의 문서가 현재 리스트중 중요도가 높지 않다면 뒤로 보낸다
            queue.append(queue.pop(0))

 

# 5397 키로거 (실버 3)

-> 문제 유형 : 스택, 구현, 그리디

Point. 스택 2개를 만들어 스택 두개의 중간 지점을 커서로 간주한다.

창영이는 강산이의 비밀번호를 훔치기 위해서 강산이가 사용하는 컴퓨터에 키로거를 설치했다. 며칠을 기다린 끝에 창영이는 강산이가 비밀번호 창에 입력하는 글자를 얻어냈다.

키로거는 사용자가 키보드를 누른 명령을 모두 기록한다. 따라서, 강산이가 비밀번호를 입력할 때, 화살표나 백스페이스를 입력해도 정확한 비밀번호를 알아낼 수 있다.

강산이가 비밀번호 창에서 입력한 키가 주어졌을 때, 강산이의 비밀번호를 알아내는 프로그램을 작성하시오.

ex) <<BP<A>>Cd-

data left_stack 커서 right_stack
<      
<      
B B    
P BP    
< B   P
A BA   P
> BAP    
>      
C BAPC    
d BAPCD    
- BAPC    

 

tc = int(input()) # 테스트케이스 개수

for i in range(tc):
    left_stack = [] # 스택 두개를 만들어, 스택 두개의 중간 지점을 커서로 간주합니다.
    right_stack = []
    data = input()
    for i in data:
        if i == '-': # 왼쪽 스택에서 원소를 삭제합니다
            if left_stack:
                left_stack.pop()
        elif i == '<': # 왼쪽 스택에서 오른쪽 스택으로 원소를 이동합니다.
            if left_stack:
                right_stack.append(left_stack.pop())
        elif i == '>': # 오른쪽스택에서 왼쪽 스택으로 왼소를 이동합니다.
            if right_stack:
                left_stack.append(right_stack.pop())
        else: # 왼쪽 스택에 원소를 삽입합니다.
            left_stack.append(i)
    left_stack.extend(reversed(right_stack)) # 오른쪽 스택을 뒤집어서 왼쪽 스택에 더해줍니다
    print(''.join(left_stack))
반응형

유형별 문제 풀이 - 기본 자료구조 - 01. 기초 문제풀이

# 2920 음계 (브론즈2)

-> 문제 유형 : 배열, 구현

다장조는 c d e f g a b C, 총 8개 음으로 이루어져있다. 이 문제에서 8개 음은 다음과 같이 숫자로 바꾸어 표현한다. c는 1로, d는 2로, ..., C를 8로 바꾼다.

1부터 8까지 차례대로 연주한다면 ascending, 8부터 1까지 차례대로 연주한다면 descending, 둘 다 아니라면 mixed 이다.

연주한 순서가 주어졌을 때, 이것이 ascending인지, descending인지, 아니면 mixed인지 판별하는 프로그램을 작성하시오.

a = list(map(int, input().split()))
ascending, descending = False, False
start = a[0]
for i in range(1,len(a)):
    if start > a[i]:
        descending = True
    elif start < a[i]:
        ascending = True
    start = a[i]

if ascending == True and descending == False:
    print('ascending')
elif ascending == False and descending == True:
    print('descending')
else:
    print('mixed')

 

# 2798 블랙잭 (브론즈2)

-> 문제유형 : 배열, 조합, 완전탐색

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.

한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.

김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.

이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.

N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

import itertools

N, M = list(map(int, input().split())) # N : 카드의 개수, M : 최대 수
card = list(map(int, input().split())) # 카드에 쓰여진 수
answer = 0

nCr = list(itertools.combinations(card, 3)) # 3가지 조합 찾아내기
nCr_sum = []
for i in nCr: # 고른 카드의 합 구하기
    nCr_sum.append(sum(i))
nCr_sum.sort() # 정렬하기

for i in nCr_sum: # M을 넘지않으면서 가까운 카드 찾아내기
    if i <= M:
        answer = i
    else:
        break
print(answer)

 

+ 동빈나 풀이

n,m = list(map(int, input().split(' ')))
data = list(map(int, input().split(' ')))

result =0
length = len(data)
sum_value = 0
for i in range(0, length):
    for j in range(i+1, length):
        for k in range(j+1, length):
            sum_value = data[i]+data[j]+data[k]
            if sum_value <= m:
                result = max(result, sum_value)

print(result)
반응형

'알고리즘 > baekjoon' 카테고리의 다른 글

[ 백준 / 파이썬 ] 19236 청소년 상어  (0) 2021.06.08
[ 백준 / 파이썬 ] 스택 수열, 프린터 큐, 키로거  (0) 2021.05.27
20210223_코테공부  (0) 2021.02.23
20210210_코테공부  (0) 2021.02.10
20210209_코테공부  (0) 2021.02.09

#12849 본대 산책 (실버1)

  • 한 건물에서 바로 인접한 다른 건물로 이동 하는 데 1분이 걸린다. 준영이는 산책 도중에 한번도 길이나 건물에 멈춰서 머무르지 않는다. 준영이는 할 일이 많아서 딱 D분만 산책을 할 것이다. (산책을 시작 한 지 D분 일 때, 정보 과학관에 도착해야 한다.) 이때 가능한 경로의 경우의 수를 구해주자.
  • D 가 주어진다 (1 ≤ D ≤ 100,000) 
  • 가능한 경로의 수를 1,000,000,007로 나눈 나머지를 출력 한다.
  • 참고
# 0 분에 어떤 지점에 도착할 수 있는 상태
# 0 : 정보과학과 1 : 전산관 2 : 미래관 3 : 신양관
# 4 : 한경직기념관 5 : 진리관 6 : 학생회관 7 : 형남공학관
DP = [1,0,0,0,0,0,0,0]

def nxt(state):
    tmp = [0 for _ in range(8)]
    tmp[0] = state[1] + state[2]
    tmp[1] = state[0] + state[2] + state[3]
    tmp[2] = state[0] + state[1] + state[3] + state[4]
    tmp[3] = state[1] + state[2] + state[4] + state[5]
    tmp[4] = state[2] + state[3] + state[5] + state[7]
    tmp[5] = state[3] + state[4] + state[6]
    tmp[6] = state[5] + state[7]
    tmp[7] = state[4] + state[6]
    return tmp

for i in range(int(input())):
    DP = nxt(DP)

print(DP[0]%1000000007)
반응형

'알고리즘 > baekjoon' 카테고리의 다른 글

[ 백준 / 파이썬 ] 스택 수열, 프린터 큐, 키로거  (0) 2021.05.27
[ 백준 / 파이썬 ] 음계, 블랙잭  (0) 2021.05.26
20210210_코테공부  (0) 2021.02.10
20210209_코테공부  (0) 2021.02.09
20210208_코테공부  (0) 2021.02.08

# 1915 가장 큰 정사각형 (골드5)

  • n×m의 0, 1로 된 배열이 있다. 이 배열에서 1로 된 가장 큰 정사각형의 크기를 구하는 프로그램을 작성하시오.
  • Point. DP로 풀기... .. 노이해... 다시 풀어보기
N, M = map(int, input().split())
A = [[0 for _ in range(M+1)] for i in range(N+1)]
# DP[i][j] = i,j까지 왔을 때, 가장 큰 정사각형의 한 변의 길이
DP = [[0 for _ in range(M+1)] for i in range(N+1)]

for i in range(N):
    for idx, j in enumerate(list(map(int, list(input())))):
        A[i+1][idx+1] = j
mx =0
for i in range(1, N+1):
    for j in range(1, M+1):
        if A[i][j]:
            DP[i][j] = min(DP[i-1][j], DP[i-1][j-1], DP[i][j-1])+1

print(max([max(i) for i in DP]) ** 2)

 

단계별풀기 - 정렬

# 2108 통계학 (실버4)

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이
  • input()으로 하면 시간초과 남 import sys sys.stdin.readline() 사용
  • 데이터 개수 세기 collections 모듈의 Counter 클래스 사용 ( 참고 )
from collections import Counter
import sys
N = int(sys.stdin.readline())
N_list = [int(sys.stdin.readline()) for _ in range(N)]
N_sort = sorted(N_list)

print(round(sum(N_list)/N)) # 반올림함수 round
print(N_sort[int(N/2)])
N_count = Counter(N_sort).most_common(2) #데이터 개수가 많은 순으로 정렬된 배열 리턴
if N > 1: # 데이터가 하나일 경우에는 out of range 뜨니까
    if N_count[0][1] == N_count[1][1]:
        print(N_count[1][0])
    else:
        print(N_count[0][0])
else:
    print(N_list[0])
print(N_sort[-1]-N_sort[0])

 

# 1427 소트인사이드 (실버5)

  • 첫째 줄에 자리수를 내림차순으로 정렬한 수를 출력한다.
n = input()
n_list = []
for i in n:
    n_list.append(i)

n_sort = sorted(n_list, reverse=True)
for i in n_sort:
    print(i,end="")

 

반응형

'알고리즘 > baekjoon' 카테고리의 다른 글

[ 백준 / 파이썬 ] 음계, 블랙잭  (0) 2021.05.26
20210223_코테공부  (0) 2021.02.23
20210209_코테공부  (0) 2021.02.09
20210208_코테공부  (0) 2021.02.08
20210204_코테공부  (0) 2021.02.04

# 2167 2차원 배열의 합 (브론즈1)

  • 2차원 배열이 주어졌을 때 (i, j) 위치부터 (x, y) 위치까지에 저장되어 있는 수들의 합을 구하는 프로그램을 작성하시오. 배열의 (i, j) 위치는 i행 j열을 나타낸다.
  • 첫째 줄에 배열의 크기 N, M(1 ≤ N, M ≤ 300)이 주어진다. 다음 N개의 줄에는 M개의 정수로 배열이 주어진다. 배열에 포함되어 있는 수는 절댓값이 10,000보다 작거나 같은 정수이다. 그 다음 줄에는 합을 구할 부분의 개수 K(1 ≤ K ≤ 10,000)가 주어진다. 다음 K개의 줄에는 네 개의 정수로 i, j, x, y가 주어진다(i ≤ x, j ≤ y).
  • point. 누적합 사용
N,M = map(int,input().split())
A = [list(map(int, input().split())) for _ in range(N)]
# DP[i][j] = (1,1) 부터 (i,j) 까지의 부분합
DP = [[0 for i in range(M+1)] for _ in range(N+1)]

for i in range(1, N+1):
    for j in range(1, M+1): #대각선 중복되므로 빼줘야됨
        DP[i][j] = DP[i-1][j] + DP[i][j-1] - DP[i-1][j-1] + A[i-1][j-1]

for _ in range(int(input())):
    i, j, x, y = map(int, input().split())
    print(DP[x][y] - DP[i-1][y] - DP[x][j-1] + DP[i-1][j-1])

 

 

*  1차원 배열 누적합

A = [i for i in range(10)]
print(A)
for i in range(1, 10):
    A[i] = A[i-1] + A[i]
print(A)

// 결과값
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
  • 3까지 합은 -> 6
  • 5부터 9까지의 합 -> 9누적합 - (5-1)누적합 = 45 - 10 = 35
  • => i부터 j까지의 합은 DP[j] - DP[i-1]

 

단계별풀기 - 정렬

# 2750 수 정렬하기 (브론즈1)

  • 첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
  • 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 

n = int(input())
num = [int(input()) for _ in range(n)]
sort_n = sorted(num)

for i in range(n):
    print(sort_n[i])

 

# 2751 수 정렬하기2 (실버5)

  • 첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다
  • 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 
  • point. 수 정렬하기 코드 제출하면 시간 초과남 -> input()으로 입력받아 메모리 초과가 날 경우, import sys sys.stdin.readline() 사용

import sys
n = int(sys.stdin.readline())
num = [int(sys.stdin.readline()) for _ in range(n)]
sort_n = sorted(num)

for i in range(n):
    print(sort_n[i])

 

# 10989 수 정렬하기3 (실버5)

  • 첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.
  • 첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다.  
  • 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.
  • point. 수 정렬하기2로 코드로 제출하면 메모리 초과 뜸 -> array를 사용한다

import sys
n = int(sys.stdin.readline())
b = [0]*10001 #수가 10,000보다 작거나 같은 자연수이기 때문
for i in range(n):
    b[int(sys.stdin.readline())] += 1  #같은 수 갯수 세기
for i in range(10001):
    if b[i] != 0:
        for j in range(b[i]): #같은 수 갯수만큼 출력하기
            print(i)

 

반응형

'알고리즘 > baekjoon' 카테고리의 다른 글

20210223_코테공부  (0) 2021.02.23
20210210_코테공부  (0) 2021.02.10
20210208_코테공부  (0) 2021.02.08
20210204_코테공부  (0) 2021.02.04
20210201_코테공부  (0) 2021.02.01

# 11055 가장 큰 증가 부분 수열 (실버2)

  • 수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오.
  • 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수열은 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 이고, 합은 113이다.
  • 첫째 줄에 수열 A의 합이 가장 큰 증가 부분 수열의 합을 출력한다.
import copy
N, A = int(input()), list(map(int, input().split()))

# DP[i] : i까지 왔을 때, 합의 최대
# 자기 자신이 제일 클 수도 있음 ex) 1000 100 10 1 -> 1000이 젤커
DP = copy.deepcopy(A) 

for i in range(1, N):
    for j in range(i):
        if A[i] > A[j]:
            DP[i] = max(A[i]+DP[j], DP[i])

#마지막이 최대라는 보장없음
#예시ㅣ -> print(DP) [1, 101, 3, 53, 113, 6, 11, 17, 24, 32]
print(max(DP))

 

+ (심화) 합이 가장 큰 증가 부분 수열의 합과 리스트 출력하기 

import copy
N, A = int(input()), list(map(int, input().split()))

# DP[i] : i까지 왔을 때, 합의 최대
# 자기 자신이 제일 클 수도 있음 ex) 1000 100 10 1 -> 1000이 젤커
DP = copy.deepcopy(A)
rev = [i for i in range(N)]
idx = 0

for i in range(1, N):
    for j in range(i):
        if A[i] > A[j] and DP[i] < A[i]+DP[j]:
            DP[i] = A[i]+DP[j]
            rev[i] = j
    if DP[idx] < DP[i]:
        idx = i

print(DP[idx])
while rev[idx] != idx:
    print(A[idx], sep=" ")
    idx = rev[idx]
print(A[idx])
// 결과값
10
1 100 2 50 60 3 5 6 7 8
113
60
50
2
1

 

+ 최장 증가 부분 수열(LIS : Longest Increasing Subsequence)

 

단계별풀기 - 브루트 포스

# 1436 영화감독 숌 (실버 5)

  • Point. 1666 2666 3666 4666 5666 6666 이 아니고 6660 6661 6662 6663... 이다.
  • 단순 반복문으로 666이 들어있는지 판별한다
n = int(input())
cnt = 0
six_n = 666
while True:
    if '666' in str(six_n):
        cnt += 1
    if cnt == n:
        print(six_n)
        break
    six_n += 1

 

반응형

'알고리즘 > baekjoon' 카테고리의 다른 글

20210210_코테공부  (0) 2021.02.10
20210209_코테공부  (0) 2021.02.09
20210204_코테공부  (0) 2021.02.04
20210201_코테공부  (0) 2021.02.01
20210129_코테공부  (0) 2021.01.29

+ Recent posts