문제

 

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1

정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

 

입력


첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 1,000,000보다 작거나 같다.

 

출력


각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.

 

예제 입력과 출력

 

 

정답

 

import sys
input= lambda : sys.stdin.readline().strip()

t=int(input())
m=[0]*1000001
m[1]=1
m[2]=2
m[3]=4

while t:
    t -= 1
    a=int(input())
    if a <= 3:
        print(m[a])
    else:
        if m[a] != 0:
            print(m[a])
            continue
        for i in range(4,a+1):
            if m[i] != 0:
                continue
            else:
                m[i]= (m[i-1]+m[i-2]+m[i-3]) % 1000000009
        print(m[a])

 

백준알고리즘 - 9095번 1, 2, 3 더하기 - 파이썬(Python)

위 문제의 응용 문제입니다.

 


백준 알고리즘 15988번 : https://www.acmicpc.net/problem/15988

 

15988번: 1, 2, 3 더하기 3

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 1,000,000,009로 나눈 나머지를 출력한다.

www.acmicpc.net

 

문제


수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.

 

입력


첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

 

출력


수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

 

예제 입력과 출력

 

 

정답

 

from collections import deque
import sys
input = lambda :sys.stdin.readline().strip()

n,k=map(int,input().split())
ch=[-1]*100001

def bfs():
    de=deque()
    de.append(n)
    ch[n] = 0

    while de:
        x=de.popleft()

        if x == k:
            return ch[k]

        if 0 <= x*2 < 100001 and ch[x*2] == -1:
            ch[x*2] = ch[x]
            de.append(x*2)
        
        for i in (x-1,x+1):
            if 0 <= i < 100001 and ch[i] == -1:
                ch[i] = ch[x]+1
                de.append(i)

print(bfs())

1697 숨바꼭질 문제에서 조금 변형된 문제입니다.

 


백준 알고리즘 13549번 : https://www.acmicpc.net/problem/13549

 

13549번: 숨바꼭질 3

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 ��

www.acmicpc.net

 

문제


영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다.

영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만들어 보려고 한다.

  1. 화면에 있는 이모티콘을 모두 복사해서 클립보드에 저장한다.
  2. 클립보드에 있는 모든 이모티콘을 화면에 붙여넣기 한다.
  3. 화면에 있는 이모티콘 중 하나를 삭제한다.

모든 연산은 1초가 걸린다. 또, 클립보드에 이모티콘을 복사하면 이전에 클립보드에 있던 내용은 덮어쓰기가 된다. 클립보드가 비어있는 상태에는 붙여넣기를 할 수 없으며, 일부만 클립보드에 복사할 수는 없다. 또한, 클립보드에 있는 이모티콘 중 일부를 삭제할 수 없다. 화면에 이모티콘을 붙여넣기 하면, 클립보드에 있는 이모티콘의 개수가 화면에 추가된다.

영선이가 S개의 이모티콘을 화면에 만드는데 걸리는 시간의 최솟값을 구하는 프로그램을 작성하시오.

 

입력

 

첫째 줄에 S (2 ≤ S ≤ 1000) 가 주어진다.

출력


첫째 줄에 이모티콘을 S개 만들기 위해 필요한 시간의 최솟값을 출력한다.

 

예제 입력과 출력

 

 

정답

 

from collections import deque
import sys
input = lambda :sys.stdin.readline().strip()

s=int(input())
ch=[[-1]*(s+1) for i in range(s+1)]

def bfs():
    de=deque()
    de.append([1,0])
    ch[1][0]=0

    while de:
        x,y=de.popleft()

        if ch[x][x] == -1: # 1번 연산
            ch[x][x] = ch[x][y]+1
            de.append([x,x])
        if x+y <= s and ch[x+y][y] == -1 : # 2번 연산
            ch[x+y][y] = ch[x][y]+1
            de.append([x+y,y])
        if x-1 >=0 and ch[x-1][y] == -1: # 3번 연산
            ch[x-1][y] = ch[x][y]+1
            de.append([x-1,y])
            
bfs()

r=ch[s][1]
for i in range(1,s):
    if ch[s][i] != -1:
        r=min(r,ch[s][i])
print(r)

이모티콘 1개에서 s개까지의 이모티콘을 화면에 만드는데 걸리는 최소 시간을 구하는 문제입니다.
bfs를 이용해 문제를 푸는데 ch를 이차원 배열로 만듭니다.


ch[화면에 나온 이모티콘 개수][클립보드의 이모티콘 개수]

 

bfs에서 1, 2, 3번 각각 연산의 경우를 실행합니다.
화면에 나온 이모티콘은 s개이고 클립보드의 이모티콘이 1부터 s-1개일때까지의 값을 비교해 가장 작은 값(최소 시간)을 출력합니다.

 


백준 알고리즘 14226번 : https://www.acmicpc.net/problem/14226

 

14226번: 이모티콘

영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다. 영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만��

www.acmicpc.net

 

문제


BOJ 알고리즘 캠프에는 총 N명이 참가하고 있다. 사람들은 0번부터 N-1번으로 번호가 매겨져 있고, 일부 사람들은 친구이다.

오늘은 다음과 같은 친구 관계를 가진 사람 A, B, C, D, E가 존재하는지 구해보려고 한다.

  • A는 B와 친구다.
  • B는 C와 친구다.
  • C는 D와 친구다.
  • D는 E와 친구다.

위와 같은 친구 관계가 존재하는지 안하는지 구하는 프로그램을 작성하시오.

 

입력


첫째 줄에 사람의 수 N (5 ≤ N ≤ 2000)과 친구 관계의 수 M (1 ≤ M ≤ 2000)이 주어진다.

둘째 줄부터 M개의 줄에는 정수 a와 b가 주어지며, a와 b가 친구라는 뜻이다. (0 ≤ a, b ≤ N-1, a ≠ b) 같은 친구 관계가 두 번 이상 주어지는 경우는 없다.

 

출력


문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

 

예제 입력과 출력

 

 

정답

 

import sys
input = lambda : sys.stdin.readline().strip()

n,m=map(int,input().split())
li=[[]*m for i in range(n)]

for i in range(m):
    a,b=map(int,input().split())
    li[a].append(b)
    li[b].append(a)

def dfs(node,d):
    print(ch)
    global r
    ch[node]=0

    if d >= 4:
        r = 1
        return

    for i in li[node]:
        if ch[i] == -1:
            dfs(i,d+1)
            ch[i]= -1

r=0
ch=[-1]*n
for i in range(n):
    dfs(i,0)
    ch[i]=-1
    if r == 1:
        break

print(r)

친구관계가 존재하는지 안하는지는 5명의 친구가 순서대로 친구관계를 이루는지를 통해 확인할 수 있습니다.

dfs를 이용해 한 친구를 기준으로 길이가 4까지 갈 수 있는지 확인했습니다.

 


백준 알고리즘 13023번 : www.acmicpc.net/problem/13023

 

13023번: ABCDE

문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

www.acmicpc.net

 

문제


폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.

  • 정사각형은 서로 겹치면 안 된다.
  • 도형은 모두 연결되어 있어야 한다.
  • 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.

정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.

아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.

테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.

테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

 

입력


첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)

둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

 

출력

 

첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

예제 입력과 출력

 

 

알고리즘 분류


브루트 포스

 

정답

 

import sys 
input = lambda : sys.stdin.readline().strip()

n,m =map(int,input().split())
a = [list(map(int,input().split())) for i in range(n)]
b = [
    [(0,1), (1,0), (1,1)],
    [(0,1), (0,2), (0,3)],
    [(1,0), (2,0), (3,0)],
    [(0,1), (0,2), (1,0)],
    [(0,1), (0,2), (-1,2)],
    [(1,0), (1,1), (1,2)],
    [(0,1), (0,2), (1,2)],
    [(1,0), (2,0), (2,1)],
    [(0,1), (1,1), (2,1)],
    [(0,1), (1,0), (2,0)],
    [(1,0), (2,0), (2,-1)],
    [(1,0), (1,1), (2,1)],
    [(0,1), (1,0), (-1,1)],
    [(0,1), (1,0), (1,-1)],
    [(0,1), (1,1), (1,2)],
    [(0,1), (0,2), (1,1)],
    [(1,0), (1,1), (1,-1)],
    [(1,0), (2,0), (1,-1)],
    [(1,0), (1,1), (2,0)]
]

def countt(x, y):
    global r
    
    for i in range(19):
        c=a[x][y]
        for j in range(3):
            nx = x + b[i][j][0]
            ny = y + b[i][j][1]
            
            if 0 <= nx < n and 0 <= ny <m:
                c += a[nx][ny]
            else:
                break
        
        r=max(r,c)

r=0
for i in range(n):
    for j in range(m):
        countt(i, j)

print(r)

 


백준 알고리즘 14500번 : https://www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변�

www.acmicpc.net

 

문제


지구 온난화로 인하여 북극의 빙산이 녹고 있다. 빙산을 그림 1과 같이 2차원 배열에 표시한다고 하자. 빙산의 각 부분별 높이 정보는 배열의 각 칸에 양의 정수로 저장된다. 빙산 이외의 바다에 해당되는 칸에는 0이 저장된다. 그림 1에서 빈칸은 모두 0으로 채워져 있다고 생각한다.

그림 1. 행의 개수가 5이고 열의 개수가 7인 2차원 배열에 저장된 빙산의 높이 정보

빙산의 높이는 바닷물에 많이 접해있는 부분에서 더 빨리 줄어들기 때문에, 배열에서 빙산의 각 부분에 해당되는 칸에 있는 높이는 일년마다 그 칸에 동서남북 네 방향으로 붙어있는 0이 저장된 칸의 개수만큼 줄어든다. 단, 각 칸에 저장된 높이는 0보다 더 줄어들지 않는다. 바닷물은 호수처럼 빙산에 둘러싸여 있을 수도 있다. 따라서 그림 1의 빙산은 일년후에 그림 2와 같이 변형된다.

그림 3은 그림 1의 빙산이 2년 후에 변한 모습을 보여준다. 2차원 배열에서 동서남북 방향으로 붙어있는 칸들은 서로 연결되어 있다고 말한다. 따라서 그림 2의 빙산은 한 덩어리이지만, 그림 3의 빙산은 세 덩어리로 분리되어 있다.

한 덩어리의 빙산이 주어질 때, 이 빙산이 두 덩어리 이상으로 분리되는 최초의 시간(년)을 구하는 프로그램을 작성하시오. 그림 1의 빙산에 대해서는 2가 답이다. 만일 전부 다 녹을 때까지 두 덩어리 이상으로 분리되지 않으면 프로그램은 0을 출력한다.

 

입력


첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 나타내는 M개의 정수가 한 개의 빈 칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 10 이하이다. 배열에서 빙산이 차지하는 칸의 개수, 즉, 1 이상의 정수가 들어가는 칸의 개수는 10,000 개 이하이다. 배열의 첫 번째 행과 열, 마지막 행과 열에는 항상 0으로 채워진다.

 

출력


첫 줄에 빙산이 분리되는 최초의 시간(년)을 출력한다. 만일 빙산이 다 녹을 때까지 분리되지 않으면 0을 출력한다.

 

예제 입력과 출력

 

 

알고리즘 분류


BFS

DFS

 

정답

 

from collections import deque
import copy
import sys
input = lambda : sys.stdin.readline().strip()

n,m=map(int,input().split())
a=[list(map(int,input().split())) for i in range(n)]

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

k = 0 #년도

def count(a): #섬의 숫자 줄이기
    aa=copy.deepcopy(a)
    
    for i in range(1,n-1):
        for j in range(1,m-1):
            s=0
            if a[i][j] > 0:
                for z in range(4):        
                    nx = i + dx[z]
                    ny = j + dy[z]

                    if 0 <= nx < n and 0 <= ny < m:
                        if a[nx][ny] == 0:
                            s += 1

                if a[i][j] - s <= 0:
                    aa[i][j] = 0
                elif a[i][j] - s > 0:
                    aa[i][j] = a[i][j] - s
    return aa

def bfs(s1,s2): #남은 섬의 개수 구하기
    de = deque()
    de.append([s1,s2])
    ch[s1][s2]=0
    
    while de:
        x, y =de.popleft()

        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]

            if 0 <= nx < n and 0 <= ny < m:
                if ch[nx][ny] == -1 and bb[nx][ny] != 0:
                    ch[nx][ny] = 0
                    de.append([nx,ny])

while True:
    k += 1
    c=0
    ch=[[-1]*m for i in range(n)] #방문여부
    
    bb=count(a)
    
    for i in range(1,n-1):
        for j in range(1,m-1):
            if bb[i][j] > 0 and ch[i][j] == -1:
                bfs(i,j)
                c += 1
    
    a=copy.deepcopy(bb)
    if c >= 2:
        print(k)
        break
    elif c == 0: #만일 빙산이 다 녹을 때까지 분리되지 않으면 
        print(0)
        break

 

빙산에서 일년후에 녹은 빙산이 두 덩어리 이상으로 분리되면 괜찮지만 그렇지 않을 경우 일년후 녹은 빙산을 가지고 또 일년 빙산을 녹여야 한다는 문제가 있었습니다.
문제의 핵심은 녹은 빙산을 다시 이용하여 빙산을 녹이는 것 같은데 간단한 방법은생각이 나지 않아 해당 빙산을 복사해서 다시 이용하겠다고 생각했습니다.

 

python 시간초과로 PyPy3로 제출했습니다.

 

1. 빙산을 녹입니다.
2-1. 섬의 개수를 세서 2 이상이면 섬을 녹이는데 걸린 년도를 출력합니다.
2-2. 섬의 개수가 0이면 빙산이 모두 녹았는데 분리되지 않아 0을 출력합니다.
3. 섬의 개수가 2미만이면 1, 2의 과정을 반복합니다.

 


백준 알고리즘 2573번 : www.acmicpc.net/problem/2573

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 �

www.acmicpc.net

 

+ Recent posts