728x90

단계별로 풀어보기 재귀의 2단계 문제

 

10870번: 피보나치 수 5

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n>=2)가 된다. n=17일때 까지 피보나치 수를 써보면 다음과 같다. 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597 n이 주어졌을 때, n번째 피보나치 수를 구하는

www.acmicpc.net

 

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 2) + fibonacci(n - 1)
n = int(input())
print(fibonacci(n))
728x90
728x90

단계별로 풀어보기 재귀의 1단계 문제

 

10872번: 팩토리얼

0보다 크거나 같은 정수 N이 주어진다. 이때, N!을 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)
n = int(input())
print(factorial(n))
728x90
728x90

단계별로 풀어보기 DFS와 BFS 9단계 문제

 

2206번: 벽 부수고 이동하기

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다. 만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동

www.acmicpc.net

이렇게 짰는데

from sys import stdin
n, m = list(map(int, stdin.readline().split()))
li = []
for i in range(n):
    li.append(stdin.readline())
import collections
q = collections.deque()
q.append((0, 0, 1, False))
visited = [[False] * m for i in range(n)]
flag = False

while q:
    cur = q.popleft()
    if cur[0] == n - 1 and cur[1] == m - 1:
        print(cur[2])
        flag = True
        break
    if not visited[cur[0]][cur[1]]:
        visited[cur[0]][cur[1]] = True
    else:
        continue
    if cur[0] - 1 >= 0 and li[cur[0] - 1][cur[1]] == '0' and not visited[cur[0] - 1][cur[1]]:
        q.append((cur[0] - 1, cur[1], cur[2] + 1, cur[3]))
    if cur[0] + 1 < n and li[cur[0] + 1][cur[1]] == '0' and not visited[cur[0] + 1][cur[1]]:
        q.append((cur[0] + 1, cur[1], cur[2] + 1, cur[3]))
    if cur[1] - 1 >= 0 and li[cur[0]][cur[1] - 1] == '0' and not visited[cur[0]][cur[1] - 1]:
        q.append((cur[0], cur[1] - 1, cur[2] + 1, cur[3]))
    if cur[1] + 1 < m and li[cur[0]][cur[1] + 1] == '0' and not visited[cur[0]][cur[1] + 1]:
        q.append((cur[0], cur[1] + 1, cur[2] + 1, cur[3]))
    if not cur[3] and cur[0] - 1 >= 0 and li[cur[0] - 1][cur[1]] == '1':
        q.append((cur[0] - 1, cur[1], cur[2] + 1, True))
    if not cur[3] and cur[0] + 1 < n and li[cur[0] + 1][cur[1]] == '1':
        q.append((cur[0] + 1, cur[1], cur[2] + 1, True))
    if not cur[3] and cur[1] - 1 >= 0 and li[cur[0]][cur[1] - 1] == '1':
        q.append((cur[0], cur[1] - 1, cur[2] + 1, True))
    if not cur[3] and cur[1] + 1 < m and li[cur[0]][cur[1] + 1] == '1':
        q.append((cur[0], cur[1] + 1, cur[2] + 1, True))
if not flag:
    print(-1)

틀렸다고 한다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10870번 피보나치 수5  (0) 2020.01.12
[백준] 10872번 팩토리얼  (0) 2020.01.12
[백준] 1697 숨바꼭질  (0) 2020.01.10
[백준] 7569번 토마토  (0) 2020.01.10
[백준] 7576번 토마토  (0) 2020.01.10
728x90

단계별로 풀어보기 DFS와 BFS의 8단계 문제

 

1697번: 숨바꼭질

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

www.acmicpc.net

최솟값을 구하는 것이므로 BFS로 풀었다. 30분 정도 걸렸다.

from sys import stdin
n, k = list(map(int, stdin.readline().split()))
import collections
q = collections.deque()
q.append((n, 0))
visited = [False] * (max(n, k) + 2)
while q:
    cur = q.popleft()
    if cur[0] == k:
        print(cur[1])
        break
    if not visited[cur[0]]:
        visited[cur[0]] = True
    else:
        continue
    if cur[0] + 1 < (max(n, k) + 2) and not visited[cur[0] + 1]:
        q.append((cur[0] + 1, cur[1] + 1))
    if cur[0] - 1 >= 0 and  not visited[cur[0] - 1]:
        q.append((cur[0] - 1, cur[1] + 1))
    if 2 * cur[0] < (max(n, k) + 2) and not visited[2 * cur[0]]:
        q.append((2 * cur[0], cur[1] + 1))

 

23일 뒤에 C++로 다시 풀어봤다.

#include <iostream>
#include <tuple>
#include <queue>
#include <vector>
using namespace std;


int main() {
	int n, k;
	cin >> n >> k;
	queue<pair<int, int>> q;
	q.push(make_pair(n, 0));
	vector<bool> visited(100001);
	while (!q.empty()) {
		pair<int, int> cur = q.front();
		q.pop();
		if (cur.first == k) {
			cout << cur.second;
			break;
		}
		visited[cur.first] = true;
		if(cur.first - 1 >= 0 && !visited[cur.first - 1])
			q.push(make_pair(cur.first - 1, cur.second + 1));
		if(cur.first + 1 <= 100000 && !visited[cur.first + 1])
			q.push(make_pair(cur.first + 1, cur.second + 1));
		if(cur.first * 2 <= 100000 && !visited[cur.first * 2])
			q.push(make_pair(cur.first * 2, cur.second + 1));
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10872번 팩토리얼  (0) 2020.01.12
[백준] 2206번 벽 부수고 이동하기 (미해결)  (0) 2020.01.11
[백준] 7569번 토마토  (0) 2020.01.10
[백준] 7576번 토마토  (0) 2020.01.10
[백준] 2178번 미로 탐색  (0) 2020.01.10
728x90

단계별로 풀어보기 DFS와  BFS의 7단계 문제

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100, 1 ≤ H ≤ 100 이다. 둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 하나의 상자에 담긴 토마토의 정보가 주어진다. 각 줄에는 상자 가로줄에 들어있는 토마

www.acmicpc.net

5단계 문제인 7576번 문제의 3차원 버전이다. 따라서 위, 아래만 더 검사하면 된다. 앞, 뒤, 오른쪽, 왼쪽은 2차원일 때에도 검사했으니까.

from sys import stdin
m, n, h = list(map(int, stdin.readline().split()))
matrix = []
for i in range(h):
    matrix.append([])
count = 0
minus = 0
zero = 0
import collections
q = collections.deque()
one = []
for i in range(h):
    for j in range(n):
        temp = list(map(int, stdin.readline().split()))
        matrix[i].append(temp)
        count += temp.count(1)
        minus += temp.count(-1)
        zero += temp.count(0)
        for k in range(m):
            if temp[k] == 1:
                q.append((i, j, k, 0))
if zero == 0:
    print(0)
else:
    ripen = 0
    result = 0
    visited = [[[False] * m for j in range(n)] for i in range(h)]
    while q:
        cur = q.popleft()
        if not visited[cur[0]][cur[1]][cur[2]]:
            visited[cur[0]][cur[1]][cur[2]] = True
            matrix[cur[0]][cur[1]][cur[2]] = 1
            ripen += 1
            result = cur[3]
        else:
            continue
        if cur[0] + 1 < h and matrix[cur[0] + 1][cur[1]][cur[2]] == 0 and not visited[cur[0] + 1][cur[1]][cur[2]]:
            q.append((cur[0] + 1, cur[1], cur[2], cur[3] + 1))
        if cur[1] + 1 < n and matrix[cur[0]][cur[1] + 1][cur[2]] == 0 and not visited[cur[0]][cur[1] + 1][cur[2]]:
            q.append((cur[0], cur[1] + 1, cur[2], cur[3] + 1))
        if cur[0] - 1 >= 0 and matrix[cur[0] - 1][cur[1]][cur[2]] == 0 and not visited[cur[0] - 1][cur[1]][cur[2]]:
            q.append((cur[0] - 1, cur[1], cur[2], cur[3] + 1))
        if cur[1] - 1 >= 0 and matrix[cur[0]][cur[1] - 1][cur[2]] == 0 and not visited[cur[0]][cur[1] - 1][cur[2]]:
            q.append((cur[0], cur[1] - 1, cur[2], cur[3] + 1))
        if cur[2] + 1 < m and matrix[cur[0]][cur[1]][cur[2] + 1] == 0 and not visited[cur[0]][cur[1]][cur[2] + 1]:
            q.append((cur[0], cur[1], cur[2] + 1, cur[3] + 1))
        if cur[2] - 1 >= 0 and matrix[cur[0]][cur[1]][cur[2] - 1] == 0 and not visited[cur[0]][cur[1]][cur[2] - 1]:
            q.append((cur[0], cur[1], cur[2] - 1, cur[3] + 1))
    if ripen == m * n * h - minus:
        print(result)
    else:
        print(-1)
728x90
728x90

단계별로 풀어보기 DFS와 BFS의 6단계 문제

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마

www.acmicpc.net

한 시간 정도 걸렸던 것 같다.

최솟값을 구하는 거니까 BFS를 이용했다.

from sys import stdin
m, n = list(map(int, stdin.readline().split()))
matrix = []
count = 0
minus = 0
zero = 0
import collections
q = collections.deque()
one = []
for i in range(n):
    temp = list(map(int, stdin.readline().split()))
    matrix.append(temp)
    count += temp.count(1)
    minus += temp.count(-1)
    zero += temp.count(0)
    for j in range(m):
        if temp[j] == 1:
            q.append((i, j, 0))
if zero == 0:
    print(0)
else:
    ripen = 0
    result = 0
    visited = [[False] * m for i in range(n)]
    while q:
        cur = q.popleft()
        if not visited[cur[0]][cur[1]]:
            visited[cur[0]][cur[1]] = True
            matrix[cur[0]][cur[1]] = 1
            ripen += 1
            result = cur[2]
        else:
            continue
        if cur[0] + 1 < n and matrix[cur[0] + 1][cur[1]] == 0 and not visited[cur[0] + 1][cur[1]]:
            q.append((cur[0] + 1, cur[1], cur[2] + 1))
        if cur[1] + 1 < m and matrix[cur[0]][cur[1] + 1] == 0 and not visited[cur[0]][cur[1] + 1]:
            q.append((cur[0], cur[1] + 1, cur[2] + 1))
        if cur[0] - 1 >= 0 and matrix[cur[0] - 1][cur[1]] == 0 and not visited[cur[0] - 1][cur[1]]:
            q.append((cur[0] - 1, cur[1], cur[2] + 1))
        if cur[1] - 1 >= 0 and matrix[cur[0]][cur[1] - 1] == 0 and not visited[cur[0]][cur[1] - 1]:
            q.append((cur[0], cur[1] - 1, cur[2] + 1))
    if ripen == m * n - minus:
        print(result)
    else:
        print(-1)
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1697 숨바꼭질  (0) 2020.01.10
[백준] 7569번 토마토  (0) 2020.01.10
[백준] 2178번 미로 탐색  (0) 2020.01.10
[백준] 1330번 두 수 비교하기  (0) 2020.01.10
[백준] 1541번 잃어버린 괄호  (0) 2020.01.10
728x90

단계별로 풀어보기 DFS와 BFS의 5단계 문제

 

2178번: 미로 탐색

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

www.acmicpc.net

BFS로 풀면 된다.

큐에 (row, col, depth)를 집어넣는다. (row, col)은 방문한 위치, depth는 (1, 1)부터 몇 칸 거쳐서 왔는지 정보이다.

from sys import stdin
import collections
n, m = list(map(int, stdin.readline().split()))
matrix = []
for i in range(n):
    matrix.append(stdin.readline())
q = collections.deque()
q.append((0, 0, 1))
visited = [[False] * m for i in range(n)]
while q:
    cur = q.popleft()
    if not visited[cur[0]][cur[1]]:
        visited[cur[0]][cur[1]] = True
        if cur[0] == n - 1 and cur[1] == m - 1:
            print(cur[2])
            break
    else:
        continue
    if cur[0] + 1 < n and matrix[cur[0] + 1][cur[1]] == "1" and not visited[cur[0] + 1][cur[1]]:
        q.append((cur[0] + 1, cur[1], cur[2] + 1))
    if cur[1] + 1 < m and matrix[cur[0]][cur[1] + 1] == "1" and not visited[cur[0]][cur[1] + 1]:
        q.append((cur[0], cur[1] + 1, cur[2] + 1))
    if cur[0] - 1 >= 0 and matrix[cur[0] - 1][cur[1]] == "1" and not visited[cur[0] - 1][cur[1]]:
        q.append((cur[0] - 1, cur[1], cur[2] + 1))
    if cur[1] - 1 >= 0 and matrix[cur[0]][cur[1] - 1] == "1" and not visited[cur[0]][cur[1] - 1]:
        q.append((cur[0], cur[1] - 1, cur[2] + 1))
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 7569번 토마토  (0) 2020.01.10
[백준] 7576번 토마토  (0) 2020.01.10
[백준] 1330번 두 수 비교하기  (0) 2020.01.10
[백준] 1541번 잃어버린 괄호  (0) 2020.01.10
[백준] 1931번 회의실 배정  (0) 2020.01.10
728x90

단계별로 풀어보기 if문의 1단계 문제

 

1330번: 두 수 비교하기

두 정수 A와 B가 주어졌을 때, A와 B를 비교하는 프로그램을 작성하시오.

www.acmicpc.net

너무 쉬운 문제라서 올리기도 민망하지만

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        if (a > b)
            System.out.println(">");
        else if (a < b)
            System.out.println("<");
        else System.out.println("==");
    }
}

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 7576번 토마토  (0) 2020.01.10
[백준] 2178번 미로 탐색  (0) 2020.01.10
[백준] 1541번 잃어버린 괄호  (0) 2020.01.10
[백준] 1931번 회의실 배정  (0) 2020.01.10
[백준] 11399 ATM  (0) 2020.01.10
728x90

단계별로 풀어보기 그리디 알고리즘의 마지막(4단계) 문제

 

1541번: 잃어버린 괄호

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이 연속되는 숫자는 없다. 수는 0으로 시작할 수 있다.

www.acmicpc.net

더하기끼리 최대한 많이 묶으면 된다.

import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.next();
        StringTokenizer st = new StringTokenizer(s, "-");
        ArrayList list = new ArrayList<>();
        while (st.hasMoreTokens()) {
            String next = st.nextToken();
            if(next.contains("+")) {
                StringTokenizer tokenizer = new StringTokenizer(next, "+");
                int sum = 0;
                while (tokenizer.hasMoreTokens()) {
                    sum += Integer.parseInt(tokenizer.nextToken());
                }
                list.add(sum);
            }
            else {
                list.add(Integer.parseInt(next));
            }
        }
        int result = list.get(0);
        for (int i = 1; i < list.size(); i++) {
            result -= list.get(i);
        }
        System.out.println(result);
    }
}

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2178번 미로 탐색  (0) 2020.01.10
[백준] 1330번 두 수 비교하기  (0) 2020.01.10
[백준] 1931번 회의실 배정  (0) 2020.01.10
[백준] 11399 ATM  (0) 2020.01.10
[백준] 11047 동전0  (0) 2020.01.10
728x90

단계별로 풀어보기 그리디 알고리즘 2단계 문제

 

1931번: 회의실배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

파이썬의 좋은 점 중 하나가 (x, y)와 같은 순서쌍을 표현하고 싶을 때 클래스를 따로 만들지 않고 튜플을 이용하면 된다는 점인 것 같다.

자바는 튜플이 없어서 클래스를 하나 만들었다.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList li = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            li.add(new Tuple(in.nextInt(), in.nextInt()));
        }
        li.sort(new Comparator() {
            @Override
            public int compare(Tuple o1, Tuple o2) {
                if (o1.y - o2.y < 0)
                    return -1;
                else if (o1.y - o2.y > 0)
                    return 1;
                else
                    return o1.x - o2.x;
            }
        });
        ArrayList order = new ArrayList<>();
        int count = 0;
        order.add(li.get(0));
        count++;
        for (int i = 1; i < n; i++) {
            if(order.get(count - 1).y <= li.get(i).x) {
                count++;
                order.add(li.get(i));
            }
        }
        System.out.println(count);
    }
}
class Tuple {
    int x;
    int y;

    public Tuple(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1330번 두 수 비교하기  (0) 2020.01.10
[백준] 1541번 잃어버린 괄호  (0) 2020.01.10
[백준] 11399 ATM  (0) 2020.01.10
[백준] 11047 동전0  (0) 2020.01.10
[백준] 1012 유기농 배추  (0) 2020.01.08

+ Recent posts