# 1080 행렬 (실버 2)

  • 0과 1로만 이루어진 행렬 A와 행렬 B가 있다. 이때, 행렬 A를 행렬 B로 바꾸는데 필요한 연산의 횟수의 최솟값을 구하는 프로그램을 작성하시오.
  • 행렬을 변환하는 연산은 어떤 3*3크기의 부분 행렬에 있는 모든 원소를 뒤집는 것이다. (0 -> 1, 1 -> 0)
  • 첫째 줄에 문제의 정답을 출력한다. 만약 A를 B로 바꿀 수 없다면 -1을 출력한다.
  • point. A,B 행렬값을 비교해서 다르면 3*3 크기만큼 flip 시켜준다
N, M = map(int, input().split())
A = [list(map(int, list(input()))) for _ in range(N)]
B = [list(map(int, list(input()))) for _ in range(N)]

def flip(x,y,A):
    for i in range(3):
        for j in range(3):
            A[x+i][y+j] ^= 1 # xor

ans = 0
for i in range(N-2):
    for j in range(M-2):
        if A[i][j] != B[i][j]:
            flip(i,j,A)
            ans +=1

if A != B:
    print(-1)
else:
    print(ans)

 

# 2014 소수의 곱 (골드2)

  • K개의 소수가 주어졌을 때, 이러한 소수의 곱들 중에서 N번째 수를 구해 보자. 단 정답은 2**31보다 작은 자연수이다.
  • point. 그리디 알고리즘 젤 어려운 문제, 네이버같은 곳에서 나옴
  • heap 우선순위 큐를 사용하여 큐 안에 있는 값들 중 최소 값을 반환한다. (힙큐 최소힙 기반)
  • 중복 처리 중요
import heapq
import copy

K,N = map(int, input().split())
p_list = list(map(int, input().split()))

lst, ck = copy.deepcopy(p_list), set() # ck 중복된 수를 포함하지 않기 위해

heapq.heapify(lst)
ith = 0

while ith < N :
    mn = heapq.heappop(lst) # 꼭대기값
    if mn in ck:
        continue
    ith += 1
    ck.add(mn)
    for i in p_list:
        if mn*i < 2**32:
            heapq.heappush(lst, mn*i)
print(mn)

 

단계별풀기 - 재귀

# 2447 별 찍기 -10(실버1)

def star(i):
    global arr
    idx = [ i for i in range(n) if (i//3**cnt_)%3 ==1]
    for i in idx:
        for j in idx:
            arr[i][j] = " "

n = int(input())
v = n
cnt = 0
while v != 1:
    v/=3
    cnt +=1
arr = [["*"]*n for _ in range(n)]
for cnt_ in range(cnt):
    star(cnt_)

print('\n'.join([''.join([str(i) for i in row]) for row in arr]))

 

# 11729 하노이 탑 이동 순서 (실버2)

  • 세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.
    1. 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
    2. 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
  • 이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.
  • point. 하노이탑 이동 규칙. n개의 원판이 있을 때, n-1개의 원판 즉, 맨 밑의 원판을 제외하고 나머지 원판들을 1번에서 2번으로 옮긴 뒤, 맨 밑의 원판을 1번에서 3번으로 옮긴다. 그리고 n-1개의 원판들을 다시 2번에서 3번으로 옮긴다.

규칙

def hanoi(disk, start, mid, end):
    if disk == 1:
        print(start, end)
    else:
        hanoi(disk - 1, start, end, mid) # 목적지가 아닌 곳으로 재귀적으로 이동
        print(start, end)
        hanoi(disk - 1, mid, start, end) # 다른 곳으로 옮겼던 원반들을 그 위에 얹는다

total_disk = int(input())
total_mvmt = 0

for disk in range(total_disk):
    total_mvmt = total_mvmt * 2
    total_mvmt += 1

print(total_mvmt)
hanoi(total_disk, 1, 2, 3)
반응형

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

20210129_코테공부  (0) 2021.01.29
20210128_코테공부  (0) 2021.01.28
20210126_코테공부  (0) 2021.01.26
20210125_코테공부  (0) 2021.01.25
20210122_코테공부  (0) 2021.01.22

# 16676 근우의 다이어리 꾸미기 (브론즈2)

  • point. 그리디 알고리즘 -> 규칙성을 찾아라
  • 0~10 => 1 / 11~110 => 2 / 111~1110 => 3 / 1111~11110 =>4 ~~
  • ex) n = 88
  • 입력받는 정수의 길이를 1로 표시
  • n이 일의 자리 정수라면 1 
  • n이 11보다 크거나 같다면 두 개의 스티커팩으로 표현 가능
  • n이 11보다 작다면(10인 경우) 한 개의 스티커팩으로 표현 가능 
N= input()
S = '1'*len(N)

if len(N) == 1:
    print(1)
elif int(N) >= int(S):
    print(len(N))
else:
    print(len(N)-1)

 

# 2437 저울 (골드3)

  • 무게가 양의 정수인 N개의 저울추가 주어질 때, 이 추들을 사용하여 측정할 수 없는 양의 정수 무게 중 최솟값을 구하는 프로그램을 작성하시오.
  • 예를 들어, 무게가 각각 3, 1, 6, 2, 7, 30, 1인 7개의 저울추가 주어졌을 때, 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값은 21이다. 
  • point. 그리디 알고리즘 -> 규칙성을 찾아라
  • 현재까지의 합 + 1 보다 큰 값이 다음 인덱스에 저장된 수라면 이전의 추들로 무게를 구할 수 없다.
n, a = int(input()), sorted(list(map(int, input().split())))
ans = 0
for i in a:
    if i <= ans +1:
        ans += i
    else:
        break
print(ans+1)

 

단계별풀기 - 기본수학2

# 1002 터렛 (실버4)

  • 조규현의 좌표 (x1, y1)와 백승환의 좌표 (x2, y2)가 주어지고, 조규현이 계산한 류재명과의 거리 r1과 백승환이 계산한 류재명과의 거리 r2가 주어졌을 때, 류재명이 있을 수 있는 좌표의 수를 출력하는 프로그램을 작성하시오.
  • 각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.
  • point. 원과 원의 접점의 개수를 구하는 문제
    1. 두 원이 일치하는 경우 -> -1, 0
    2. 두 원이 한 점에서 만나는 경우(외접, 내접) -> 1
    3. 두 원이 만나지 않는 경우 -> 0
    4. 두 원이 두 점에서 만나는 경우 -> 2
t = int(input())
for i in range(t):
    x1, y1, r1, x2, y2, r2 = map(int, input().split())
    d = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
    rs = r1 + r2
    rm = abs(r1 - r2)
    if d == 0:
        if r1 == r2:
            print(-1)
        else:
            print(0)
    else:
        if d == rs or d == rm:
            print(1)
        elif d < rs and d > rm:
            print(2)
        else:
            print(0)

 

단계별풀기 - 재귀

# 10872 팩토리얼 (브론즈 3)

  • 0보다 크거나 같은 정수 N이 주어진다. 이때, N!을 출력하는 프로그램을 작성하시오.
def fac(n):
    if n == 0:
        return 1
    elif n == 1:
        return 1
    return  n * fac(n-1)

N = int(input())
print(fac(N))

 

# 10870 피보나치수 5 (브론즈2)

  • 첫째 줄에 n번째 피보나치 수를 출력한다.
def f(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return  f(n-1) + f(n-2)

N = int(input())
print(f(N))
반응형

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

20210128_코테공부  (0) 2021.01.28
20210127_코테공부  (0) 2021.01.27
20210125_코테공부  (0) 2021.01.25
20210122_코테공부  (0) 2021.01.22
20210121_코테공부  (0) 2021.01.21

Q. CPU 스케줄링이란 무엇이고 왜 필요한가?

  • 프로세스가 최고의 성능을 내기 위해 자원을 어떤 프로세스에 얼마나 할당하는지 정책을 만드는 것CPU 스케줄링이라고 합니다. 프로세스들이 CPU를 효율적으로 사용하기 위해 필요합니다.
  • 선점 스케줄링과 비선점 스케줄링이 있습니다.

 

Q. 선점형 스케줄링은 무엇이고 알고리즘은 무엇이 있나요?

  • 프로세스가 CPU를 할당받아 실행중이더라도 운영체제가 CPU를 강제로 빼앗을 수 있는 방식으로 CPU 처리 시간이 매우 긴 프로세스가 CPU 사용 독점을 막을 수 있어 효율적인 운영이 가능합니다. 하지만 잦은 문맥 교환으로 오버헤드가 많이 발생합니다.
  • 선점형 알고리즘으로는 SRT, 라운드로빈, 다단계큐, 다단계 피드백 큐 스케줄링이 존재합니다.
    1. SRT(Shortest Remaining Time) 스케줄링 : 짧은 시간 순서대로 프로세스를 수행합니다. 남은 처리 시간이 더 짧은 프로세스가 준비 큐에 들어오면 그 프로세스가 바로 선점됩니다. SJF의 선점 버전이라고 할 수 있습니다.
    2. 라운드로빈(Round-Robin, RR) 스케줄링 : 각 프로세스는 같은 크기의 CPU 시간을 할당 받고 선입선출에 의해 행된다. 할당시간이 너무 크면 선입선출과 다를 바가 없어지고, 너무 작으면 문맥교환이 잦아져 오버헤드가 증가합니다.
    3. 다단계 큐(Muti-level Queue) 스케줄링 : 우선순위에 따라 준비큐를 여러 개 사용하는 방법으로 각각의 큐는 자신의 스케줄링 알고리즘을 수행하며, 큐와 큐 사이에도 우선순위를 부여합니다.
    4. 다단계 피드백 큐 스케줄링 : 다단계 큐와 비슷하나 프로세스들이 큐를 이동할 수 있습니다.

 

Q. 비선점형 스케줄링은 무엇이고 알고리즘은 무엇이 있나요?

  • 프로세스가 CPU를 점유하고 있다면 이를 빼앗을 수 없는 방식으로 필요한 문맥 교환만 일어나기 때문에 오버헤드가 상대적으로 적지만 프로세스의 배치에 따라 효율성 차이가 많이 납니다.
  • 비선점형 알고리즘으로는 FIFO, SJF, HRN, 우선순위 스케줄링이 존재합니다.
    1. FIFO=FCFS(First Come First Served) 스케줄링 : 선입선출 방식으로, 준비 큐에 도착한 순서대로 CPU를 할당합니다. 작업 완료 시간을 예측하기는 용이하나 덜 중요한 작업이 중요한 작업을 기다리게 할 수 있습니다.
    2. SJF(Shortest Job First) 스케줄링 : 준비 큐에 있는 프로세스 중 실행시간이 가장 짧은 작업부터 CPU를 할당합니다. 평균 대기 시간을 감소시킵니다.
    3. HRN(Hightest response ratio next) 스케줄링 : SJF + Aging을 합친 알고리즘으로, 실행시간과 대기 시간을 모두 고려해 우선순위를 정합니다.
    4. 우선순위(priority) 스케줄링 : 프로세스에게 우선순위를 부여하여 우선순위가 높은 순서대로 처리합니다. SJF, HRN, SRTF도 우선순위 스케줄링 알고리즘의 일종입니다.

 

Q. 비선점형 SJF와 선점형 SRT 비교하시오

  • 비선점 스케줄링 SJF 기법을 선점 형태로 변경한 기법이 SRT이다.
  • SJF는 실행시간이 가장 짧은 프로세스
  • SRT는 현재 실행중인 프로세스의 남아 있는 실행 시간과 새로운 프로세스의 실행 시간을 비교하여 짧은 것

ex) 아래와 같은 세가지 작업이 있다고 가정한다.

비선점형 SJF(Shortest Job First)의 경우

작업시간이 짧은게 우선이지만, 비선점형이기 때문에 시작한건 끝내야됨

선점형 SRT(Shortest Remaining Time)의 경우

작업시간이 짧은게 우선이지만, 선점형이기 때문에 남은 작업이 짧은 것이 우선이다

 

참고자료 : CPU스케줄링, [IT 기술면접 준비자료] CPU 스케줄링 기법, 선점, 비선점 스케줄링

반응형

# 1439 뒤집기 (실버5)

  • 0과 1로만 이루어진 문자열에서 연속구간 뒤집기를 통해 한문자로만 이루어진 문자열을 만들려 할때, 뒤집기 시행횟수 구하기
  • point. 그리디 알고리즘 -> 규칙성을 찾아라
  • 뒤에 문자랑 비교해서 같은 문자끼리 뭉텅이 구하기 -> 뭉텅이//2
s = input()
count = 0
for i in range(len(s)-1):
    if s[i] != s[i+1]:
        count +=1
print((count+1)//2)

 

단계별풀기 - 기본수학2

# 1085 직사각형에서 탈출 (브론즈3)

  • 한수는 지금 (x, y)에 있다. 직사각형의 왼쪽 아래 꼭짓점은 (0, 0)에 있고, 오른쪽 위 꼭짓점은 (w, h)에 있다. 직사각형의 경계선까지 가는 거리의 최솟값을 구하는 프로그램을 작성하시오.
  • point. (0.0)에 가까운 x,y 거리도 고려해야한다.
x, y, w, h = map(int, input().split())
print(min(w-x, h-y, x, y))

 

# 3009 네 번째 점 (브론즈3)

  • 세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.
x_list = []
y_list = []
for i in range(3):
    x, y = list(map(int, input().split()))
    x_list.append(x)
    y_list.append(y)

for i in range(3):
    if x_list.count(x_list[i]) == 1:
        x = x_list[i]
    if y_list.count(y_list[i]) == 1:
        y = y_list[i]
print(x,y)

 

# 4153 직각삼각형 (브론즈3)

  • 주어진 세변의 길이로 삼각형이 직각인지 아닌지 구분하시오.
  • 각 입력에 대해 직각 삼각형이 맞다면 "right", 아니라면 "wrong"을 출력한다.
while True:
    rec_list = list(map(int, input().split()))
    if rec_list[0] == 0 & rec_list[1] == 0 & rec_list[2] == 0:
        break
    rec_max = max(rec_list)
    rec_list.remove(rec_max)

    if rec_max**2 == rec_list[0]**2 + rec_list[1]**2:
        print("right")
    else:
        print("wrong")

 

# 3053 택시 기하학 (브론즈3)

  • 첫째 줄에는 유클리드 기하학에서 반지름이 R인 원의 넓이를, 둘째 줄에는 택시 기하학에서 반지름이 R인 원의 넓이를 출력한다. 정답과의 오차는 0.0001까지 허용한다.
  • 유클리드 기하학 원의 넓이 : 반지름 * 반지름 * 3.1415...(파이)
  • 택시 기하학에서의 반지름이 R인 원의 넓이란, “두 대각선의 길이가 2R인 마름모의 넓이” 와 같다
import math
r = int(input())
print(r*r*math.pi)
print(r*r*2)
반응형

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

20210127_코테공부  (0) 2021.01.27
20210126_코테공부  (0) 2021.01.26
20210122_코테공부  (0) 2021.01.22
20210121_코테공부  (0) 2021.01.21
20210120_코테공부  (0) 2021.01.20

단계별풀기 - 기본수학2

# 9020 골드바흐의 추측 (실버1)

  • 짝수를 두 소수의 합으로 나타내는 표현을 그 수의 골드바흐 파티션이라고 한다.
  • 각 테스트 케이스에 대해서 주어진 n의 골드바흐 파티션을 출력한다. 출력하는 소수는 작은 것부터 먼저 출력하며, 공백으로 구분한다.
  • 만약 가능한 n의 골드바흐 파티션이 여러 가지인 경우에는 두 소수의 차이가 가장 작은 것을 출력한다.
  • point. 시간초과 에라토스테네스의 체 사용해서 소수 구하기 
    • prime 값이 True면 소수
  • point. 두 소수의 차이가 가장 작은것을 출력한다 & 작은 소수부터 출력한다 -> 중간값부터 확인해본다
    • n = 8 이면 4,4 -> 3,5(break) -> 2,6 -> 1,7 순으로 확인
    • n = 10 이면 5,5(break) -> 4,6 -> 3,7 -> 2,8 -> 1,9 순으로 확인한다. 
    • n = 16  이면 8,8, -> 7,9 -> 6,10 -> 5,11(break) -> ...
def isprime(n):
    n += 1
    prime = [True] * n  # n개의 [True]가 있는 리스트 생성
    for i in range(2, int(n ** 0.5) + 1):  # n의 제곱근까지만 검사
        if prime[i]:  # prime[i]가 True일때
            for j in range(2 * i, n, i):  # prime 내 i의 배수들을 False로 변환
                prime[j] = False
    return prime

for _ in range(int(input())):
    n = int(input())
    prime_list = isprime(n)
    half = n//2
    for i in range(half, 1, -1):
        if prime_list[i] and prime_list[n-i]:
            print(i, n-i)
            break

 

반응형

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

20210126_코테공부  (0) 2021.01.26
20210125_코테공부  (0) 2021.01.25
20210121_코테공부  (0) 2021.01.21
20210120_코테공부  (0) 2021.01.20
20210119_코테공부  (0) 2021.01.19

단계별풀기 - 기본수학2

# 4948 베르트랑 공준 (실버2)

  • 각 테스트 케이스에 대해서, n보다 크고, 2n보다 작거나 같은 소수의 개수를 출력한다.
  • point. 시간초과 에라토스테네스의 체 사용해서 소수 구하기
def isprime(m, n):
    count = 0
    prime = [True] * n  # n개의 [True]가 있는 리스트 생성
    for i in range(2, int(n ** 0.5) + 1):  # n의 제곱근까지만 검사
        if prime[i]:  # prime[i]가 True일때
            for j in range(2 * i, n, i):  # prime 내 i의 배수들을 False로 변환
                prime[j] = False

    for i in range(m, n):
        if i > 1 and prime[i] == True:  # 1 이상이면서 남은 소수들을 출력
            count+=1
    return count

while True:
    n = int(input())
    n_count = 0
    if n==0:
        break
    print(isprime(n+1,n*2+1)) # n< <=2n

 

반응형

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

20210125_코테공부  (0) 2021.01.25
20210122_코테공부  (0) 2021.01.22
20210120_코테공부  (0) 2021.01.20
20210119_코테공부  (0) 2021.01.19
20210118_코테공부  (0) 2021.01.15

Q. IPC(Inter Process Communication)이란 무엇인가요?

프로세스 간에 서로 데이터를 주고받는 방법을 말합니다. 프로세스는 커널이 제공하는 IPC설비를 이용하여 프로세스 간 통신을 할 수 있습니다. 대표적으로 메시지 교환과 데이터 공유 방법이 있습니다.

  1. Message passing : 커널(OS)가 메모리 보호를 위해 대리 전달해주는 것을 말합니다. 따라서 안전하고 동기화 문제가 없습니다. 하지만 성능이 떨어진다는 단점을 가지고 있습니다.
  2. shared memory : 두 프로세스간의 공유된 메모리를 생성 후 이용하는 것을 말합니다. 성능은 좋지만 동기화의 문제가 발생합니다.

  동기화(Synchronization), 두 개의 프로세스 A,Bshared memory를 이용해 데이터를 주고받을 때 A가 쓰면 B가 읽어가야 하는데 A가 쓰고 난 뒤인지 전인지 알 수 있는 방법이 없다. 그래서 A가 다 썼다고 알려줘야 B가 읽어갈 수 있다. 이와 같이 프로세스 또는 스레드들이 수행되는 시점을 조절하는 것이 동기화이다.

반응형

Q. PCB(Process Control Block)란 무엇이고 왜 필요한가요?

  • 운영체제가 프로세스를 제어하기 위해 이전 작업에 대한 정보를 저장해 놓은 곳으로, 프로세스 메타데이터(상태 정보)들을 저장하는 구조체입니다. 이것은 프로세스 상태관리와 문맥교환(Context Switching)을 위해 필요합니다.

+ PCB에 저장되는 정보는?

PID(프로세스 고유번호), 상태(준비, 대기, 실행...), 포인터, 우선순위, 레지스터 관련 정보 등등

 

+ Context Switching?

CPU가 이전의 프로세스 상태를 PCB에 보관하고, 또 다른 프로세스의 정보를 PCB에서 읽어 레지스터에 적재하는 과정을 말합니다.

ex) 인터럽트 발생, 실행 중인 cpu 사용 허가시간 모두 소모, 입출력을 위해 대기하는 경우 등

반응형

'cs지식 > Operating System' 카테고리의 다른 글

[OS] CPU스케줄링  (0) 2021.01.25
[OS] IPC(Inter Process Communication)  (0) 2021.01.20
[OS] 시스템 콜(System Call)  (0) 2021.01.20
[OS] 인터럽트(Interrupt)  (0) 2021.01.15
[OS] 프로세스 주소 공간  (0) 2021.01.14

+ Recent posts