# 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

[ AI 면접 구성 (1시간~1시간반 소요) ]

자기소개 > 기본질문 > 성향파악 > 상황대처 > 보상선호 > 전략게임 > 심층대화

(상황대처, 심층대화는 회사 마다 다름)

 

[ 자기소개 & 기본질문 1. 성격의 장단점 2. 해당 직무(또는 회사) 지원동기  ]

  • 60초의 준비시간 + 90초의 답변시간
  • 자기소개 & 기본질문 스크립트 준비와 암기
  • 미리 스크립트를 짜놓고 천천히 말해도 시간 안에 대답할 수 있도록 간략하게 정리하기
  • 일정한 목소리 톤과 빠르기
  • 답변의 내용은 합격/불합격에 영향을 크게 미치지 않는다고 생각함
  • 화면 보기? 카메라 보기? -> 상관 없고 한곳을 응시하는 것이 좋음

 

[ 성향 파악 ]

  • 약 160개의 문항
  • 무조건 솔직하고 일관성 있게 -> 신뢰성과 직결됨
  • 함정질문에 절대 빠지지 말자! -> 모르면 모른다고 하기 
    • ex1) 나는 00현상에 대해 들어본적 있다
    • ex2) 나는 00와 관련된 000협약에 대해 들어본 적이 있다

 

[ 상황대처 ]

  • 상황을 주어주고 이 상황에 어떻게 대답할지 말하라
  • 20초 이상 답변 시 제출 가능(최대 60초)
  • 답변이 짧다면 타이머를 보면서 말을 늘릴 필요 있음
  • 상황에 적절한 표정을 보여주는 것도 필요
    • ex) 내가 너무 가고싶었던 콘서트 티켓을 친구가 암표로 팔고 있다. 그 친구가 나에게 이것을 암표로 팔려고 한다면 어떤 말을 하겠는가?
    • ex) 아무 문제가 없는 옷을 고객이 환불해달라고 오면 어떻게 말하겠는가?
    • ex) 우리 회사는 자율 출퇴근제를 시행하고 잇다. 그런데 A대리가 업무시간에 업무에 집중하지 않고 영화를 보면서 시간을 보내고 있다. 어떻게 말하겠는가?

 

[ 보상 선호 ]

  • 미래지향으로 하는 것을 추천
  • ex) 다음과 같은 조건이라면, 지난 달 성과에 대한 성과급을 어떻게 받으시겠습니까?

 

[ 심층 대화 ] -> 성향 검사랑 같은 플로우여야함

유형1) 성향 체크 유형

  • 기본 1차 질문 (5초 안에 예/아니오로 대답)
  • 1차 질문을 바탕으로 하는 2차 추가질문 등장(30초 준비시간, 60초 답변시간)

ex) 000님은 직관적인편인가요? (1차 질문) 이성 or 직관

    000님이 직관적 성격이 아니라면, 직관적 판단으로 손해입은 경험을 말해주세요(2차 질문)

ex) 000님은 본인을 존중하지 않는 사람도 존중해야한다고 생각하나요?(1차 질문)

  그렇게 생각하기 어려우셨을텐데 그런 생각을 하게된 이유가 뭔가요? (2차 질문)

   000님은 회사 후배가 아무런 이유없이 000님을 무시한다고 했을때 어떻게 하실건가요?(2차 질문)

 

유형2) 회사/직무 유형

  • 회사 또는 직무에 대한 지원자의 관심을 측정하는 문항
  • 무슨 말이라도 해야 분석 및 채점 가능 모른다고 해서 새로운 질문이 나오지 않음
  • 지원 회사/직무(전공) 관련 질문 받을 가능성이 높아지는 추세

ex) 지원한 산업과 관련된 3가지 전공 개념을 나열해놓고 하나를 선택해서 적용사례를 간단하게 말해보시오

ex) it직무 - 블록체인의 작업 증명 방식을 설명하시오

 

[ AI면접 게임 10개  ]

  • point. 게임의 점수는 합격 여부에 큰 영향을 미치지 않는다
  • 틀리더라도 다시 빠르게 집중하는 모습!
  • 절대 포기하지 않는다
  • 나의 모든 모습은 녹화되고 있다.
  1. 감정 맞히기
  2. 공쌓기 게임(하노이의 탑) -> 보기와 이동 가능 횟수 제시 (하노이의 탑 어플)
  3. 색 - 글자 일치 게임 -> 양쪽에 문구가 뜨는데 왼쪽은 의미만 오른쪽은 색만 생각하기
  4. 자음 - 모음, 짝수 - 홀수 일치 게임 -> 천천히 틀리지 않게
  5. 공 무게 비교하기 -> 저울질 한거 하나 새거 하나 올리면서 비교하기
  6. 날씨 맞히기
  7. 카드 뒤집기 -> 함정카드 존재  위험 감수 or 회피 성향 파악하기 위한 문항
  8. N-back -> 불빛이 들어오는 위치 기억해 2,3 back (Dual Nback 어플)
  9. 입길이 맞히기 -> 주의. 포인트는 정답을 맞췄을 때 랜덤으로 지급됨
  10. 도형 맞추기

 

[ 감정 맞히기 ] -> 약 50문제?

  • 무표정, 기쁨, 슬픔(눈꼬리, 입꼬리 내려감), 무서움, 경멸, 화남, 놀라움, 역겨움
  • 화남 vs 역겨움(코 찡그림)
  • 무서움(미간, 입) vs 놀람(눈 커지고, 입 벌어짐)
  • 경멸(한쪽 입꼬리가 올라감) vs 역겨움 

 

[ 날씨 맞히기 ] -> 난이도 최상

  • 똑같은 문제가 연달아 나왔을때 틀리면 안됨
  • 온도 습도 풍향 기압에 따라 맑음 흐림 판단
  • 온도 습도 조합 흐림 / 풍향 기압 조합은 맑음

 

반응형

'잡동사니' 카테고리의 다른 글

[SSAFY] 싸피 6기 합격 후기(자소서, SW적성진단, Interview)  (1) 2021.07.23
JavaScript의 기본  (0) 2020.07.13
[Spring] Spring tomcat 오류  (0) 2020.06.18
[Mysql] Mysql 재설치  (0) 2020.06.18
[JSP] JSP 내장객체  (0) 2020.06.16

# 17406 배열 돌리기 4 (골드4)

  • 다시 풀어보기
  • Point. DFS, 방향벡터, 백트레킹 기법 사용
from copy import deepcopy

N, M, K = map(int, input().split()) # 배열 A크기 N,M, 회전 연산 개수 K
A = [list(map(int,input().split())) for _ in range(N)] # 배열 A 수
Q = [tuple(map(int, input().split())) for _ in range(K)] # 회전 연산 정보
dx,dy = [1,0,-1,0],[0,-1,0,1]   # 방향벡터 남서북동
ans = 10000 # 배열 A의 값의 최솟값

def value(arr): # 행의 최소값
    return min([sum(i) for i in arr])

def convert(arr, qry): # 회전
    (r, c, s) = qry # 중심점 (r,c) 거리 s
    r, c = r-1, c-1 # 좌표가 0,0 시작이기 때문에 -1 해줌
    new_arr = deepcopy(arr)
    for i in range(1, s+1):
        rr, cc = r-i, c+i
        for w in range(4): # 방향 4번 바꿈
            for d in range(i*2): #
                rrr, ccc = rr + dx[w], cc+dy[w]
                new_arr[rrr][ccc] = arr[rr][cc]
                rr, cc = rrr, ccc
    return new_arr

def dfs(arr, qry):
    global ans # 전역변수 설정
    if sum(qry) == K: # 쿼리를 다 처리했을 경우
        ans = min(ans, value(arr)) # 최소값 저장
        return
    for i in range(K):
        if qry[i]:
            continue
        new_arr = convert(arr, Q[i]) # 쿼리 회전
        qry[i] = 1  # 백트래킹 기법
        dfs(new_arr, qry)
        qry[i] = 0

dfs(A,[0 for i in range(K)])
print(ans)

 

단계별풀기 - 브루트 포스

# 1018 체스판 다시 칠하기(실버5) (참고)

  • 크기가 n*m이고, 흰색과 검은색으로 막 칠해져 있는 보드판이 있다.
  • 이 보드판을 잘라서 8*8크기의 체스판을 만들려고 한다.
  • 체스판은 흰색과 검은색이 번갈아가며 체크무늬를 이루어야한다.
  • 보드판을 잘라서, 체스판을 만들기 위해서 알맞게 색을 고쳐서 체크무늬를 만들어야 한다.
  • 고쳐야 하는 색의 최소값을 구하라
  • Point. 인덱스 합이 짝수인지 홀수인지로 체크무늬를 판단할 수 있다.

n, m = map(int, input().split())
board = list()
mini = list()

for _ in range(n):
    board.append(input())

for a in range(n - 7): # 8*8로 자르기
    for i in range(m - 7):
        idx1 = 0
        idx2 = 0
        for b in range(a, a + 8):
            for j in range(i, i + 8):              # 8X8 범위를 B와 W로 번갈아가면서 검사
                if (j + b)%2 == 0:
                    if board[b][j] != 'W': idx1 += 1
                    if board[b][j] != 'B': idx2 += 1
                else :
                    if board[b][j] != 'B': idx1 += 1
                    if board[b][j] != 'W': idx2 += 1
        mini.append(idx1)                          # W로 시작했을 때 칠해야 할 부분
        mini.append(idx2)                          # B로 시작했을 때 칠해야 할 부분

print(min(mini))

 

ex) n = 10, m = 13일 경우 len(mini) = (10-7)*(13-7)*2 = 36개 그 값들 중 가장 작은 수 출력

반응형

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

20210209_코테공부  (0) 2021.02.09
20210208_코테공부  (0) 2021.02.08
20210201_코테공부  (0) 2021.02.01
20210129_코테공부  (0) 2021.01.29
20210128_코테공부  (0) 2021.01.28

# 1932 정수 삼각형 (실버1)

  • 첫째 줄에 합이 최대가 되는 경로에 있는 수의 합을 출력한다.
  • Point. 모든 경로를 따지면 2^50 -> 이번생에 못푼다
  • DP문제 (다음 상태를 저장하고 사용함)
    1. 상태를 정의한다 
    2. 점화식을 찾는다(구한다) 
    3. 시간복잡도를 계산한다
    4. 코딩한다(재귀 or 반복문 사용)
N = int(input())
# DP[i][j] : i,j 도착했을 때 최대값
# DP[i][j] = max(DP[i-1], DP[i-1][j]) + A[i][j]
A = [[0 for _ in range(N+1)] for i in range(N+1)]
DP = [[0 for _ in range(N+1)] for i in range(N+1)]

for i in range(1, N+1):
    tmp = list(map(int, input().split()))
    for j in range(1, i+1):
        A[i][j] = tmp[j-1]

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

print(max(DP[-1]))

(오른쪽 : 예시 입력값 / 왼쪽 : DP 출력값 -> DP의 마지막 줄에 max값이 최대값이다)

 

단계별풀기 - 브루트 포스

# 7568 덩치 (실버5)

  • 우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩치가 각각 (x, y), (p, q)라고 할 때 x > p 그리고 y > q 이라면 우리는 A의 덩치가 B의 덩치보다 "더 크다"고 말한다.
  • 여러분은 입력에 나열된 사람의 덩치 등수를 구해서 그 순서대로 첫 줄에 출력해야 한다. 단, 각 덩치 등수는 공백문자로 분리되어야 한다.
  • point. 정렬 ㄴㄴ, 그냥 자기보다 크고 무거운(둘 다 큰) 사람이 몇 명인지 쟤서 자기 등수만 정하면 된다.
tc = int(input())
student_list = []

for _ in range(tc):
    x, y = map(int, input().split())
    student_list.append((x, y))

for i in student_list:
    rank = 1
    for j in student_list:
        if i[0] < j[0] and i[1] < j[1]:
                rank += 1
    print(rank, end = " ")
반응형

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

20210208_코테공부  (0) 2021.02.08
20210204_코테공부  (0) 2021.02.04
20210129_코테공부  (0) 2021.01.29
20210128_코테공부  (0) 2021.01.28
20210127_코테공부  (0) 2021.01.27

# 12100 2048(Easy) (골드2)

  • 어렵... 또 풀어보자...ㅠ
  • 이 게임에서 한 번의 이동은 보드 위에 있는 전체 블록을 상하좌우 네 방향 중 하나로 이동시키는 것이다. 이때, 같은 값을 갖는 두 블록이 충돌하면 두 블록은 하나로 합쳐지게 된다. 한 번의 이동에서 이미 합쳐진 블록은 또 다른 블록과 다시 합쳐질 수 없다. (실제 게임에서는 이동을 한 번 할 때마다 블록이 추가되지만, 이 문제에서 블록이 추가되는 경우는 없다)
  • 첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2보다 크거나 같고, 1024보다 작거나 같은 2의 제곱꼴이다. 블록은 적어도 하나 주어진다.
  • 최대 5번 이동시켜서 얻을 수 있는 가장 큰 블록을 출력한다.

from copy import deepcopy

N = int(input())
Board = [list(map(int, input().split())) for i in range(N)] # n*n 보드 입력받기

def rotate90(B, N): #판 90도 회전시키기(암기할것)
    NB = deepcopy(B) # 배열 복사하기 NB = B 하면 주소값만 복사됨
    for i in range(N):
        for j in range(N):
            NB[j][N-i-1] = B[i][j] # 90도 돌리기
    return NB

def convert(lst, N): # 슬라이드 했을 때 결과물
    new_list = [i for i in lst if i]
    for i in range(1, len(new_list)):
        if new_list[i-1] == new_list[i]: #같은수이면
            new_list[i-1] *= 2 # 합치고
            new_list[i] = 0 # 나머지 제거
    new_list = [i for i in new_list if i]
    return new_list + [0] * (N-len(new_list))

def dfs(N, B, count):
    ret = max([max(i) for i in B]) #보드의 최대값
    if count == 0: # 5번 다 돌았을 때 최대값 출력
        return ret
    for _ in range(4): # 상하좌우 이동 경우의 수
        X = [convert(i, N) for i in B] # 슬라이드
        if X != B:
            ret = max(ret, dfs(N, X, count-1))
        B = rotate90(B, N) # 회전
    return  ret

print(dfs(N, Board, 5))
반응형

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

20210204_코테공부  (0) 2021.02.04
20210201_코테공부  (0) 2021.02.01
20210128_코테공부  (0) 2021.01.28
20210127_코테공부  (0) 2021.01.27
20210126_코테공부  (0) 2021.01.26

경쟁상태(Race Condition)

Q. 경쟁상태(Race Condition)이란 무엇인가요?

  • 프로세스가 어떤 순서로 데이터에 접근하느냐에 따라 결과값이 달라질 수 있는 상황을 말합니다.
  • 둘 이상의 입력이나 조작이 동시에 일어나 의도하지 않은 결과를 가져오는 경우를 말합니다.
  • 동시 접근 시 자료의 일관성을 해치는 결과가 나타날 수 있습니다.
  • 경쟁 상태도 교착상태의 종류 중에 하나입니다.

 

교착상태(DeadLock)

Q. 데드락(교착상태)이 무엇인가요? 발생 조건에 대해 말해주세요

  • 데드락은 프로세스가 자원을 얻지 못해서 다음 처리를 하지 못하는 상태를 말하며, 시스템적으로 한정된 자원을 여러 곳에서 사용하려고 할 때 발생합니다.
  • 발생 조건으로는 상호 배제, 점유 대기, 비선점, 순환 대기 모두가 성립해야 합니다.
    • 상호 배제 : 자원은 한 번에 한 프로세스만 사용할 수 있음
    • 점유 대기 : 최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용하고 있는 자원을 추가로 점유하기 위해 대기하는 프로세스가 존재해야 함
    • 비선점 : 다른 프로세스에 할당된 자원을 사용이 끝날 때까지 강제로 빼앗을 수 없음
    • 순환 대기 : 프로세스 집합에서 순환 형태로 자원을 대기하고 있어야 함

 

Q. 회피 기법인 은행원 알고리즘이 무엇인가요?

  • 운영체제를 안전상태를 유지할 수 있는 요구만을 수락하고 불안전 상태를 초래할 사용자의 요구는 나중에 만족될 수 있을 때까지 계속 거절합니다.

+ 안전상태와 불안전상태

안전상태 불안전상태
교착상태가 일어날 가능성 없음
프로세스가 요구한 양만큼 자원 할당 가능
안전 순서열 존재함
교착상태가 일어날 가능성 있음
프로세스가 요구한 양만큼 자원 할당 불가능
안전 순서열 존재안함

시스템은 안전상태에서 불안정 상태로 변할 수 있다.

 

Q. 교착상태 해결방안은 무엇이 있나요?

  • 교착상태 예방, 회피, 탐지, 회복이 있습니다.
    • 예방 : 교착 상태 발생 조건 중 하나를 제거하면서 해결한다(자원 낭비 심함)
    • 회피 : 교착 상태 발생 시 피해나가는 방법
    • 탐지 : 자원 할당 그래프를 통해 교착 상태를 탐지해 그에 대한 오버헤드 발생함
    • 회복 : 교착 상태를 일으킨 프로세스를 종료하거나, 할당된 자원을 해제시켜 회복시키는 방법

 

세마포어(Semaphore)와 뮤텍스(Mutex)

Q. 세마포어(Semaphore)와 뮤텍스(Mutex)의 공통점과 차이점은 무엇인가요?

  • 둘 다 병행 처리를 위한 프로세스 동기화 기법입니다. (여러 프로세스나 쓰레드가 공유 자원에 접근하는 것을 제어하기 위한 방법)
  • 세마포어는 공유 자원에 세마포어의 변수만큼의 프로세스(or 쓰레드)에 접근할 수 있습니다. 반면에 뮤텍스는 오직 1개만의 프로세스(or 쓰레드)만 접근할 수 있습니다.
  • 현재 수행중인 프로세스가 아닌 다른 프로세스가 세마포어를 해제할 수 있습니다. 하지만 뮤텍스는 락(lock)을 획득한 프로세스가 반드시 그 락을 해제해야 합니다.

세마포어 P(임계 구역 들어가기 전에 수행),V(임계 구역에서 나올 때 수행) 연산

뮤텍스 : 접근 조율을 위해 락(lock)과 해제(unlock) 사용, 상태가 1과 0로 이진 세마포어로 부르기도 함

세마포어와 뮤텍스 참고자료

 

Q. 임계구역(Critical Section)이란 무엇인가요?

  • 각 프로세스에서 공유 데이터를 접근하는 프로그램 코드 부분으로 한 프로세스가 임계 구역을 수행할 때는 다른 프로세스가 접근하지 못하도록 해야 합니다.

반응형

# 16768 Mooyo Mooyo (골드4)

  • 셀 높이 (1≤N≤100) 및 10 셀 너비
  • 각 셀은 비어 있거나 (0으로 표시) 9 가지 색상 중 하나 (문자 1..9로 표시)의 건초입니다. 중력으로 인해 건초 더미가 아래로 떨어 지므로 건초 더미 아래에 0 셀이 없습니다.
  • 두 셀이 가로 또는 세로로 직접 인접하고 0이 아닌 동일한 색상을 갖는 경우 동일한 연결된 영역에 속합니다. 최소한으로 연결된 지역이 존재할 때에 K세포, 건초 더미가 모두 사라지고 0으로 변합니다. 이러한 연결된 영역이 동시에 여러 개 있으면 모두 동시에 사라집니다. 그 후 중력으로 인해 건초 더미가 아래로 떨어져 0이 된 결과 K세포 중 일부를 채울 수 있습니다. 결과 구성에서 다시 적어도 크기의 연결된 영역이있을 수 있습니다. K세포. 만약 그렇다면, 그것들도 사라지고 (동시에, 그러한 영역이 여러 개인 경우), 중력은 나머지 세포를 아래쪽으로 당기고, 적어도 크기의 연결된 영역이 없을 때까지 프로세스가 반복됩니다. K에 있다.
  • Mooyo Mooyo 보드의 상태를 감안할 때 이러한 작업이 발생한 후 보드의 최종 사진을 출력하십시오.
  • point. 함수 나눠서 풀기 / Flood Fill /  dfs사용하기 / 갯수세기, 지우기, 내리기로 나눠서 코드 작성
  • 반복해서 풀어보기
def new_array(N):
    return [[False for i in range(10)] for _ in range(N)]

N, K = map(int, input().split())
M = [list(input()) for _ in range(N)]
ck = new_array(N)
ck2 = new_array(N)
dx, dy = [0,1,0,-1], [1,0,-1,0] #방향벡터 설정

def dfs(x,y): # 갯수세기
    ck[x][y] = True # 그룹에 포함되어 있는가
    ret = 1
    for i in range(4): # 4방향 검사
        xx,yy = x+dx[i], y+dy[i]
        if xx<0 or xx>=N or yy<0 or yy>=10: # 구간 내에 있는지 확인
            continue
        if ck[xx][yy] or M[x][y] != M[xx][yy]: # 체크가 되어 있거나 연결이 안되거나
            continue
        ret += dfs(xx,yy)
    return ret

def dfs2(x,y, val): # 지우기
    ck2[x][y] = True # 지워도 되는가
    M[x][y] = '0' # 0으로 바꿔줌
    for i in range(4):
        xx, yy = x + dx[i], y + dy[i]
        if xx < 0 or xx >= N or yy < 0 or yy >= 10:  # 구간 내에 있는지 확인
            continue
        if ck2[xx][yy] or M[xx][yy] != val:
            continue
        dfs2(xx,yy,val)

def down(): #내리기
    for i in range(10): # 세로줄부터 확인하기
        tmp = []
        for j in range(N):
            if M[j][i] != '0': #0이 아닌 수들 저장
                tmp.append(M[j][i])
        for j in range(N-len(tmp)): #0이 아닌 수의 갯수 빼고 0 채우고
            M[j][i] = '0'
        for j in range(N-len(tmp),N): #나머지 수 채워넣기
            M[j][i] = tmp[j- (N -len(tmp))]

while True:
    exist = False
    ck = new_array(N)
    ck2 = new_array(N)
    for i in range(N):
        for j in range(10):
            if M[i][j] == '0' or ck[i][j]: # 0이거나 이미 체크했으면 넘어가기
                continue
            res = dfs(i,j) # 개수 세기
            if res >= K:    # 개수가 K보다 같거나 크면
                dfs2(i,j, M[i][j]) # 지우기
                exist = True
    if not exist:
        break
    down() # 내리기

for i in M:
    print(''.join(i))

 

 

단계별풀기 - 브루트 포스

# 2798 블랙잭 (브론즈2)

  • N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.
n,m = map(int, input().split())
n_list = list(map(int, input().split()))
sum_list = []
for i in range(n):
    for j in range(i+1,n):
        for k in range(j+1,n):
            nsum = n_list[i] + n_list[j] + n_list[k]
            if nsum <= m:
                sum_list.append(nsum)

print(max(sum_list))

 

# 2231 분해합 (브론즈2)

  • 어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.
  • 첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.
  • 자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.
  • point. 숫자 각자리 더하기 list(map(int, str())) 사용

1) 틀린 답 -> 생성자가 없는 경우 0을 출력해야함을 간과함

n = int(input())
for i in range(1,n+1):
    div_num = list(map(int, str(i)))
    sum_num = i +sum(div_num)
    if sum_num == n:
        print(i)
        break

 

2) 정답

N = int(input())
print_num = 0
for i in range(1, N+1):
    div_num = list(map(int, str(i)))
    sum_num = i + sum(div_num)
    if(sum_num == N):
        print_num = i
        break
print(print_num)
반응형

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

20210201_코테공부  (0) 2021.02.01
20210129_코테공부  (0) 2021.01.29
20210127_코테공부  (0) 2021.01.27
20210126_코테공부  (0) 2021.01.26
20210125_코테공부  (0) 2021.01.25

+ Recent posts