구슬 탈출 2 성공

 

문제

스타트링크에서 판매하는 어린이용 장난감 중에서 가장 인기가 많은 제품은 구슬 탈출이다. 구슬 탈출은 직사각형 보드에 빨간 구슬과 파란 구슬을 하나씩 넣은 다음, 빨간 구슬을 구멍을 통해 빼내는 게임이다.

보드의 세로 크기는 N, 가로 크기는 M이고, 편의상 1×1크기의 칸으로 나누어져 있다. 가장 바깥 행과 열은 모두 막혀져 있고, 보드에는 구멍이 하나 있다. 빨간 구슬과 파란 구슬의 크기는 보드에서 1×1크기의 칸을 가득 채우는 사이즈이고, 각각 하나씩 들어가 있다. 게임의 목표는 빨간 구슬을 구멍을 통해서 빼내는 것이다. 이때, 파란 구슬이 구멍에 들어가면 안 된다.

이때, 구슬을 손으로 건드릴 수는 없고, 중력을 이용해서 이리 저리 굴려야 한다. 왼쪽으로 기울이기, 오른쪽으로 기울이기, 위쪽으로 기울이기, 아래쪽으로 기울이기와 같은 네 가지 동작이 가능하다.

각각의 동작에서 공은 동시에 움직인다. 빨간 구슬이 구멍에 빠지면 성공이지만, 파란 구슬이 구멍에 빠지면 실패이다. 빨간 구슬과 파란 구슬이 동시에 구멍에 빠져도 실패이다. 빨간 구슬과 파란 구슬은 동시에 같은 칸에 있을 수 없다. 또, 빨간 구슬과 파란 구슬의 크기는 한 칸을 모두 차지한다. 기울이는 동작을 그만하는 것은 더 이상 구슬이 움직이지 않을 때 까지이다.

보드의 상태가 주어졌을 때, 최소 몇 번 만에 빨간 구슬을 구멍을 통해 빼낼 수 있는지 구하는 프로그램을 작성하시오.

입력

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B' 로 이루어져 있다. '.'은 빈 칸을 의미하고, '#'은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, 'O'는 구멍의 위치를 의미한다. 'R'은 빨간 구슬의 위치, 'B'는 파란 구슬의 위치이다.

입력되는 모든 보드의 가장자리에는 모두 '#'이 있다. 구멍의 개수는 한 개 이며, 빨간 구슬과 파란 구슬은 항상 1개가 주어진다.

출력

최소 몇 번 만에 빨간 구슬을 구멍을 통해 빼낼 수 있는지 출력한다. 만약, 10번 이하로 움직여서 빨간 구슬을 구멍을 통해 빼낼 수 없으면 -1을 출력한다.

예제 입력 1 복사

5 5
#####
#..B#
#.#.#
#RO.#
#####

예제 출력 1 복사

1

예제 입력 2 복사

7 7
#######
#...RB#
#.#####
#.....#
#####.#
#O....#
#######

예제 출력 2 복사

5

 

문제 해결 

1. 구조를 하나씩 나눠서 생각하자. (공은 함께 움직임으로 같이 묶어서 생각, 공이 벽에 부딧칠경우, 공이 만날경우 등등..) 

2. (), []는 아예 구조가 다름으로 visited할때 유의 하자. 

import time
from collections import deque
import sys

inputs = sys.stdin.readline
N,M = list(map(int,inputs().split()))

maps = []
for i in range(N): 
    row = list(inputs().strip())
    maps.append(row)
    if 'R' in row: 
        ry, rx = [i, row.index('R')]

    if 'B' in row: 
        by, bx = [i, row.index('B')]

move = [[-1,0],[1,0],[0,-1],[0,1]]
q = deque()
q.append([ry, rx, by, bx])
visited = [] # 방문여부를 판단하기 위한 리스트
visited.append((ry, rx, by, bx))
s = time.time()
# find start point 
def bfs(q, maps):     
    
    cnt = 0 
    while q: 
        for _ in range(len(q)): 
            ry, rx, by, bx = q.popleft()
            # print(ry,rx,by,bx)
            if cnt > 10: # 조건에서는 10번 이하로 움직이라고 하였음.
                print(-1)
                return 
            if maps[ry][rx] == 'O': 
                print(cnt)
                return 
            
            for dy, dx in move : 
                nry, nrx = ry, rx # 빨간색 공 
                nby, nbx = by, bx # 파란색 공 

                while True : # 계속 해당 방향으로 쭉 가기  
                    nry += dy 
                    nrx += dx
                    if maps[nry][nrx] == '#': #벽에 부딧치면 나오기 
                        nry -= dy 
                        nrx -= dx
                        break
                    if maps[nry][nrx] == 'O': # 빨간공이 들어가버린다면
                        break
                
                while True : # 계속 해당 방향으로 쭉 가기  
                    nby += dy
                    nbx += dx
                    if maps[nby][nbx] == '#': #벽에 부딧치면 나오기 
                        nby -= dy
                        nbx -= dx
                        break
                    if maps[nby][nbx] == 'O': # 만약에 파란공이 들어가버린다면? 
                        break 

                if maps[nby][nbx] == 'O': 
                    continue 
            
                if nry == nby and nrx == nbx: #만약에 가다가 만났다면!!
                    if abs(nrx - rx) + abs(nry - ry) > abs(nbx - bx) + abs(nby - by): 
                        nry -= dy
                        nrx -= dx
                    else:
                        nby -= dy
                        nbx -= dx

                if (nry, nrx, nby, nbx) not in visited: # 방문해본적이 없는 위치라면 새로 큐에 추가 후 방문 처리
                    q.append((nry, nrx, nby, nbx))
                    visited.append((nry, nrx, nby, nbx))
                    # print(time.time()-s)
                
        cnt += 1 # 다음큐가 벽에 부딧쳤을떄 시작한다. 
    print(-1)
    
bfs(q, maps)

 

 

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 512 MB 92774 28560 21129 29.266%

문제

총 N개의 시험장이 있고, 각각의 시험장마다 응시자들이 있다. i번 시험장에 있는 응시자의 수는 Ai명이다.

감독관은 총감독관과 부감독관으로 두 종류가 있다. 총감독관은 한 시험장에서 감시할 수 있는 응시자의 수가 B명이고, 부감독관은 한 시험장에서 감시할 수 있는 응시자의 수가 C명이다.

각각의 시험장에 총감독관은 오직 1명만 있어야 하고, 부감독관은 여러 명 있어도 된다.

각 시험장마다 응시생들을 모두 감시해야 한다. 이때, 필요한 감독관 수의 최솟값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 시험장의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

둘째 줄에는 각 시험장에 있는 응시자의 수 Ai (1 ≤ Ai ≤ 1,000,000)가 주어진다.

셋째 줄에는 B와 C가 주어진다. (1 ≤ B, C ≤ 1,000,000)

출력

각 시험장마다 응시생을 모두 감독하기 위해 필요한 감독관의 최소 수를 출력한다.

예제 입력 1 복사

1
1
1 1

예제 출력 1 복사

1

예제 입력 2 복사

3
3 4 5
2 2

예제 출력 2 복사

7

 

문제 해결 

1. 단순하게 계산문제임으로 문제를 이해를 하고 계산하면된다. 

import sys
import math
inputs = sys.stdin.readline

N = int(inputs())
A_list = list(map(int, inputs().split()))
B, C = list(map(int,inputs().split()))
count = 0
for student in A_list: 
    count += 1
    remain_student = student - B
    if remain_student > 0: 
        count += math.ceil(remain_student / C)
    else: 
        pass

print(count)

 

반응형

Introduction 

최근 알고리즘 테스트를 하면서 느낀점은 시뮬레이션, DFS/BFS는 그래도 손에 익기 시작했는데 아직까지 Stack과 큐의 문제만 나오는 경우에서는 잘 못 푸는 나의 모습을 발견하였다.. 

 

이번에 공부를 하면서 스택/큐의 개념에 대해서 다시 공부를 하였으며 어떠한 방법들이 있는지 다시 되돌아볼수 있었다. 

 

많은 블로그를 참고를 하였지만 결국 개념은 스택의 경우는 FILO(First in Last out) 큐의 경우는 FIFO(First in First out)이라는 것을 명심해두자. 

 

Solution

아직 많이 부족한 나지만 문제를 풀다보면 스택과 큐를 풀수 있는 실마리를 찾는게 매우 중요하다.

또한 스택/큐 로 풀면 되겠다고 생각하더라도 문제 해결과정을 머리에서 빨리 돌아가야지 풀수있다. 

 

그렇기에 내가 빨리 풀수 있다고 느낀점은 다음과 같았다. 

1. 효율성을 생각해보기 

2. 그림으로 그려보기

 

첫번쨰 효율성의 경우에서는 보통 샘플이 10,000 이하로 주는 경우가 많다. 이경우에서는 단순하게 $O(N^2)$로 생각해보면 time complexity가 높겠네 생각이 들기 마련이다. 

그렇게 되면 스택, 큐, 해시로 풀수 있겠네라고 생각해볼수 있따. 

두번째는 확실하게 느낀점이지만 그림으로 그리면 쉽게 생각이 되어진다. 스택과 큐의 그림은 쉽게 그릴수 있지만 직접그려본 사람이 없지 않는가라고 생각이 든다. 

그렇기 떄문에 고수가 아닌이상 그리면서 문제를 풀어보자. !!

 

Problem

내가 스택을 이용해서 푼 문제들은 프로그래머스의 고득점 Kit에서 참고하여 풀었다 .

Level2이상은 대부분 코테에서 통과할만한 수준이라고 하여서 해당방법 위주로 정리하였다.

 

문제1 : https://school.programmers.co.kr/learn/courses/30/lessons/42586 기능개발 

 

프로그래머스

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

programmers.co.kr

해당문제의 경우에서는 

작업 개수에 걸린 시간과 그에 따른 시간을 측정해서 최종 시간을 return하는 문제이다. 

내가 푼 방법은 Stack으로 풀었기 떄문에  그방법을 공유해본다

import math
def solution(progresses, speeds):
    ## 일단 progress당 걸리는 시간을 미리 계산해보자. 
    work_days = [math.ceil((100 - progress)/work_time) \
        for progress, work_time in zip(progresses, speeds)] # 소요시간 미리 계싼
    
    if len(work_days) == 1: # 만약에 하나라면 지금 걸리는 시간 출력
        return [work_days[0]]
    
    front = 0 
    answer = []
    for idx, _ in enumerate(work_days): 
        if work_days[idx] > work_days[front]: # 앞으로 온다음에 CUT!!!
            answer.append(idx-front)
            front = idx
    answer.append(len(work_days) -  front)
    return answer

그림으로 그리면 Stack의 형태로 그려진다. 

만약 `Work_days` 라는 변수가 [7,3,9]라고 나온다고 하면 최종 return 은 [2,1]로 나온다. 

7,4,9를 stack으로 만들어서 넣으면 되다

 

 

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

문제 설명

트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며, 다리는 weight 이하까지의 무게를 견딜 수 있습니다. 단, 다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.

예를 들어, 트럭 2대가 올라갈 수 있고 무게를 10kg까지 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.

경과 시간다리를 지난 트럭다리를 건너는 트럭대기 트럭

따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.

solution 함수의 매개변수로 다리에 올라갈 수 있는 트럭 수 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭 별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.

제한 조건
  • bridge_length는 1 이상 10,000 이하입니다.
  • weight는 1 이상 10,000 이하입니다.
  • truck_weights의 길이는 1 이상 10,000 이하입니다.
  • 모든 트럭의 무게는 1 이상 weight 이하입니다.
입출력 예

 

문제풀이 

중요한건 다리를 큐로 생각하고 진행한다는점 

 

from collections import deque
def solution(bridge_length, weight, truck_weights):
    
    # 2개의 큐 구조를 사용해서 문제를 풀어보자. 
    q = deque(truck_weights)
    weight_q = deque([0] * bridge_length) # 다리를 큐 모양으로 만들자. 
    curr_weigth = 0 
    answer = 0 
    
    while q : # bright 작동
        answer += 1

        curr_weigth -= weight_q.popleft()
        if curr_weigth + q[0] <= weight:
            curr_weigth += q[0]
            weight_q.append(q.popleft())
        else: 
            weight_q.append(0)
            
    answer += bridge_length
    return answer

 

 

반응형

스터디 참여 동기 & 나의 모습

항상 해외 주식에 관심이 많아서 ETF나 개별주식(Nvidia, Apple etc)등 다양하게 투자를 하였습니다. 

하지만 주변 사람들이 주식시장이 안 좋다고 하면 저도 모르게 불안해지고 내가 팔면 다시 주식이 올라가서 손해를 보는 상황도 많이 발생을 하였습니다. ㅠㅠ

 

이를 해결하고자 여러 시도를 하였는데  책을 읽자니 지루하고 유튜브를 보자니.. 재미가 없고 공부를 하고 싶고.. 이러한 고민중에 여자친구를 통해 추천을 받은 강의가 있었으니.. 그건 바로!! 따블대디 스터디였습니다. 

 

찾아보니 커리큘럼이 초급부터 중급까지 푸짐하게 있는 것을 보고 강의 열리자마자 바로 연락을 드렸습니다.

 

특히, 제가 필요한 모든 니즈들을 충족시키기 위해 너무 좋은 조건들이었습니다. 

인스타 그램보고 바로 연락을 드렸는데 .. 다행히도 합격이었습니다. 

 

 

 

총 5주간이 시작이 되었으며 저는 아쉽게도 마지막까지 완주를 못해서 너무나도 후회되지만!!!.. 

제가 배웠던 스터디와 장점에 대해서 리뷰를 남겨볼려고 합니다. 

 

1. 매일매일 루틴과제 

과제는 매일매일 독서와 주식의 체크리스트, 그리고 뉴스인증합니다. 

저는 뉴스를 잘 안보는데 이 스터디를 통해서 매일매일 확인하고 퇴근후에는 주식을 체크할 수 있어서 너무나도 좋았습니다. 

습관처럼 매일 하게 되니 트렌드도 알고 너무 재미있더라고요 

 

2. 톡강의

강의 같은 경우는 톡강의를 통해서 진행이 되어지다보니 언제 어디서나 들을 수 있어서 너무 편리했습니다. (내용이 궁금하신 분들은 꼭 신청해서 강의를 해보시길) 

 

3.  데일리 과제 

이렇게 끝난 강의는 네이버나 개인 블로그에 올려서 과제를 업로드 함으로써 복습 + 실력향상도 보장이 됩니다. 

 

제가 적극 추천하는 건 과제인데요 시간은 소비가 되지만 배우고 나면 재미있고 차트 보는 것과 주식을 보는 시야가 확 바뀌게 되더라고요. (과제 진짜 실력향상 제대로 됩니다) 

 

 

 

늦게라도 복습을 하면서 계속해서 달려보려고 합니다. 

 

5주간 스터디를 통해 변화한 나의 모습 (장점)

이렇게 꽉 찬 강의와 커리큘럼을 통해서 제가 변화된 저의 모습에 대해서 말해보겠습니다. 

1.  회사에 대한 가치 판단이 달라짐

이전에서는 친구를 통해서 유튜브를 통해서 이 주식이 뜬다!! 하면 넣었지만 지금은 이 회사의 수익은 주력이 무엇인지, 매출은 어떻게 나오는지 그리고 경쟁사는 무엇이든지 등등 생각을 하면서 투자의 결정을 내릴 수 있게 되었다.

특히 강의에서 제공해 주신 표를 통해서 가치 판단을 할 수 있으니 더 선택에 대해서 더욱 신뢰를 할수 있다!!

할수 있었음

2. 차트를 보았을 때 피해야 될 지점에 대해서 판단 가능

이전에서는 투자의 그래프는 보지도 않았고 그냥 5년 치 그래프를 보면서 떨어지니까 사야지 하고 추가매수를 했던 경험들이 있다. 

하지만 강의를 하고 난 후에 반등점인지 크로스하여서 오히려 내려가는 지점인지 판단할 수 있는 시야를 판단할수 있었다. 

(노란색처럼 올라가는지 내려가는지 대략적인 판단이 가능!!) 

3. ETF / 배당주  투자에 대해서 배울 수 있다.

ETF에 대해서 종류도 알 수 있으며 배당주는 어떤 것이 있는지 전체적으로 많은 것을 배울 수 있었습니다. 

저는 확실히 성격상 ETF에 더 많이 투자하게 되더라고요 ㅎㅎ 

 

 

나에게 주는 칭찬 + 앞으로 나의 계획

저는 사실은 칭찬을 받기에는 많이 부족했습니다. 

5주 차까지 다 못 달렸거든요..  하지만 3주 동안 열심히 달렸는데 너무나도 많은 것을 배우고 시야가 바뀌는 시간을 가졌습니다. 

심지어 다시 2기를 들을까 생각도 많이 듭니다!! 너무 값진 강의와 내용들과 자료를 제공해 주어서 가성비가 너무 좋은 강의였습니다. 

한 가지의 칭찬을 스스로에게 한다면 그래도 매일매일 루틴이 잡혀서 주기적인 주식과 해외 증시와 뉴스를 보는 게 습관화과 된 것이 아니지 않을까 싶습니다. 

앞으로의 계획은 다음과 같습니다!!

1. 아직 다 못 끝낸 강의를 개인적으로라도 다 끝내기

2. 본격적인 ETF/ 배당주에 주식을 투자하고 합니다. 

3. 매월 최소 100만 원이라도 꼭꼭 벌자!!

4. 매일 루틴(뉴스, 증시)은 항상 확인하고 다니자 

 

강의를 들으실까 고민하시는 분들은 꼭 신청하고 실력 향상과 투자의 즐거움을 배우길 바랍니다. 

 

반응형

+ Recent posts