C++ 19

[Boj] 백준 C++ #16948 데스 나이트

📍 문제 링크 : https://www.acmicpc.net/problem/16948 📍 알고리즘 분류 : BFS 📍 문제 풀이이 문제는 큐를 이용해서 BFS로 해결할 수 있다. (r,c)의 위치에서 이동할 수 있는 칸은 아래 그림과 같이 총 6개이다. 따라서 한 위치에 대해 이동할 수 있는 6개의 위치를 모두 탐색해주면 된다.체스판을 넘어가거나, 이미 방문한 위치가 아니면 큐에 넣어준다.이미 방문했다면, 지금 방문한 것은 최단 횟수의 방문이 아니라는 것이므로 고려해줄 필요가 없다. 모든 지점은 처음으로 방문했을 때가 최단 횟수의 방문이다. 위 과정을 큐가 빌 때까지, 혹은 목표 지점에 도달할 때까지 반복한다. 이 문제의 핵심 로직은 모든 지점은 처음으로 방문했을 때가 최단 횟수의 방문이라는 것이다..

Boj 2025.01.07

[Boj] 백준 C++ #2138 전구와 스위치

📍 문제 링크 : https://www.acmicpc.net/problem/2138 📍 알고리즘 분류 : 그리디 알고리즘 📍 문제 풀이 신기한 점이 어떤 전구를 먼저 켜고 끄든, 순서가 중요하지 않다는 것이다!따라서 우리는 첫 번째 전구부터 순서대로 탐색하면 된다. 그리디하게. 현재에 최적이 되도록.첫 번째 전구를 목표 상태와 비교하고 다르다면 전구의 상태를 바꾸고, 같다면 그냥 두면 된다. 그런데 전구는 자신의 왼쪽, 자신, 자신의 오른쪽 이렇게 3개의 전구의 상태에 영향을 미치게 되는데그리디하게 접근할 경우 이 조건이 훨씬 쉽게 만들어진다. 현재 보고 있는 i번째 전구를 변경하고자 할 경우 할 수 있는 것은 i+1번째 전구를 누르는 것이라는 것이다! i-1번째 전구나 i번째 전구를 누르면 안되는..

Boj 2025.01.05

[Boj] C++ #1339 단어 수학

📍 문제 링크https://www.acmicpc.net/problem/1339 📍 알고리즘 분류그리디 📍 문제 풀이직관적으로 높은 자리에 큰 수가 와야된다는 것을 파악할 수 있다. 그런데 단어가 하나가 아니기 때문에, 어떤 단어에서는 높은 자리수의 알파벳이 다른 단어에서는 가장 낮은 자리수에 위치해있을 수도 있다. 따라서 모든 단어를 종합하여 판단해야 한다. ABC와 CADB가 주어졌다고 해보자.단어 수의 합은 (100*A + 10*B + C) + (1000*C + 100*A + 10*D + B) = (1000*C + 200A + 11B + C)가 될 것이다.이게 최대가 되기 위해서는 가장 큰 수를 곱하는 알파벳부터 9, 8, 7, 6, .. 순서대로 바꿔주면 된다.따라서 C = 9, A = 8, ..

Boj 2025.01.04

[Boj] 백준 C++ #1202 보석 도둑

📍문제 링크https://www.acmicpc.net/problem/1202 📍알고리즘 분류그리디, 우선순위 큐 📍 풀이 방법최대한 많은 보석을 훔치기 위해서는 최대한 비싼 보석을, 많이 담아야 한다.따라서 비싼 보석부터 담아야 하는데, 최대로 용량을 채울 수 있는 가방에 넣어야 한다.반복문을 통해 가방을 하나씩 그리디하게 보면서 넣을 보석을 정해준다.우선순위 큐를 이용해서 하나의 가방 안에 들어갈 수 있는 무게의 보석들 중 가격이 가장 비싼 것을 담으면 된다. 어떤 가방부터 보아야할까?용량이 큰 가방부터 본다면, 비싼데 크기가 작은 보석이 용량이 큰 가방에 담길 것이다. 더 보석을 가져갈 수 있을텐데 용량이 낭비될 것이다.따라서 용량이 작은 가방부터 탐색한다. 작은 가방에 담기는 무게 중에서 비싼..

Boj 2024.12.27

[알고리즘] 정렬알고리즘 #6 힙 정렬 (Heap Sort)

📍 힙 정렬 (Heap Sort)힙 소트는 힙 구조를 이용해 정렬하는 알고리즘이다.힙 구조란 완전 이진 트리의 일종인 자료구조로 MaxHeap과 MinHeap이 있다. MaxHeap은 루트노드가 가진 값은 자식 노드가 가진 값보다 크거나 같다. MinHeap은 반대로 루트노드가 자식노드보다 작거나 같다. 힙 소트에서는 MaxHeap을 사용한다.1) 정렬되지 않은 배열을 힙 구조로 바꾼다. (construct heap)2) 최상위 루트 노드를 뽑아 가장 마지막 원소와 교체한다. (extract)3) 루트노드부터 마지막 원소 전까지 heap구조로 만든다. (heapify / fixheap)4) 2)로 돌아가 모든 노드를 추출할 때까지 반복한다. 📍 C++ 구현 코드class Solution {public..

알고리즘 2024.10.23

[알고리즘] 정렬알고리즘 #5 퀵 정렬 (Quick Sort) - Romuto, Hoare

📍 퀵 정렬 (Quick Sort)퀵 정렬은 빠르다고 해서 퀵 정렬이다. 먼저 퀵 소트의 기본 흐름은 아래와 같다.1) 가장 왼쪽 원소를 pivot으로 선정 (pivot 선정 방식은 바꿀 수 있음)2) 배열 내 원소들을 pivot보다 작은 것 / pivot보다 큰 것 이렇게 두 개로 분류3) 각각의 배열 내에서 다시 1)부터 반복 (recursive) 📍 C++ 구현 코드퀵소트를 구현하는 방식에는 Romuto의 방식, Hoare의 방식 두 개가 있다. 각 방식의 코드가 아래에 순서대로 있다. // Romutoclass Solution {public: void quicksort(vector& nums, int start, int end){ if(start sortArray(vector..

알고리즘 2024.10.23

[알고리즘] 정렬알고리즘 #4 합병정렬 (Merge Sort)

📍 합병정렬 (Merge Sort)합병 정렬은 Divide & Conquer (분할정복) 방식을 기반으로 한 정렬이다. 배열을 쪼개고 쪼갠 뒤 합치는(merge) 과정에서 정렬이 된다. 그래서 Merge Sort이다. 📍 C++ 구현 코드class Solution {public: void merge(vector& nums, int start, int mid, int end){ int n = nums.size(); vector tmp(n+1); for(int i=0;i& nums, int start, int end){ if(start sortArray(vector& nums) { mergesort(nums,0,nums.size()-1)..

알고리즘 2024.10.23

[알고리즘] 정렬알고리즘 #3 버블정렬 (Bubble Sort)

📍 버블정렬 (Bubble Sort) 🫧버블 정렬은 정렬되는 모습이 버블버블하다.앞에서부터 계속 바로 이웃한 원소와 스왑스왑스왑스왑해서 맨 뒤에 가장 큰 원소를 넣어둔다. 그 다음엔 다시 처음부터 스왑스왑스왑스왑해서 n-2에도 가장 큰 원소를 넣는다. 계속 이웃한 원소에서 swap을 진행하면서 나아가기 때문에 전반적으로 앞에서부터 뒤까지 정렬이 조금씩 조금씩 진행되고, 정확한 정렬은 맨 뒤에서부터 하나씩 진행된다. 전반적으로 정렬이 되기 때문에 버블버블하게 거품이 올라오는 듯하다. 📍 C++ 구현 코드class Solution {public: vector sortArray(vector& nums) { int n = nums.size(); for(int i=n-2;i>=..

알고리즘 2024.10.22

[알고리즘] 정렬알고리즘 #2 선택정렬 (Selection Sort)

📍 선택정렬 (Selection Sort)가장 작은 값을 찾아 선택한다. 정렬되지 않은 배열의 첫 번째 원소부터 현재 원소이고, 그 뒤의 모든 원소를 비교해가며 가장 작은 원소를 찾는다. 가장 작은 원소를 현재 원소와 교체한다. 그러면 점점 앞에서부터(가장 작은 수부터) 순서대로 정렬되어간다.우리가 실제로 실물 카드를 정렬한다고 했을 때, 선택정렬을 사용할 사람은 없을 것 같다. 가장 작은 수를 찾아서 앞에다가 놓아가며 정렬하는 원리이지만 가장 작은 수를 맨 첫 번째 원소와 교체하기 때문이다. 우리가 실물 카드를 가지고 있다면 교체가 아니라 그냥 작은 수를 앞에다가 놓았을 것이다. 하지만 프로그램으로 구현하려면 원소의 자리를 채워주기 위해 교체가 필요했다. 실제 세상에서 사용되지는 않지만 프로그램으로 ..

알고리즘 2024.10.22

[알고리즘] 정렬알고리즘 #1 삽입정렬 (insertion Sort)

📍 삽입 정렬 (Insertion Sort)삽입 정렬은 실제로 내가 카드를 가지고 있다고 생각하면 더 이해가 쉬운 것 같다. 정렬되지 않고 나열된 카드 중 두 번째 카드를 들어 손에 쥔다. 그러면 내가 두 번째 카드를 들고 있으므로 두 번째 칸이 빌 것이다. 바로 앞의 카드와 비교하여 내가 들고 있는 카드보다 크다면 앞 카드를 한 칸 뒤로 민다. 해당 카드 바로 뒤는 비어있다. 카드를 밀어서 빈 공간을 채워주면 된다. 이를 반복하다가 내가 들고 있는 카드보다 큰 카드가 나오면 지금 빈 공간에 내가 들고 있는 카드를 내려놓는다.우리가 실제로 숫자카드를 가지고 정렬하고자 할 때 사용하곤 하는 직관적인 방법이라고 생각할 수 있다. 📍 C++ 구현 코드class Solution {public: vect..

알고리즘 2024.10.22