C++ PS 1๋‹จ๊ณ„: ๊ธฐ์ดˆ ๋ฌธ๋ฒ• ์™„์ „์ •๋ณต

๐ŸŽฏ 0. PS ํ•„์ˆ˜ ํ—ค๋”์™€ ๋งคํฌ๋กœ

๊ธฐ๋ณธ ํ—ค๋” ํŒŒ์ผ๋“ค

// ํ•„์ˆ˜ ๊ธฐ๋ณธ ํ—ค๋”
#include <iostream>    // cin, cout
#include <vector>      // vector ์ปจํ…Œ์ด๋„ˆ
#include <string>      // string ํด๋ž˜์Šค
#include <algorithm>   // STL ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•จ์ˆ˜๋“ค

// ์ถ”๊ฐ€ ์œ ์šฉํ•œ ํ—ค๋”๋“ค
#include <queue>       // queue, priority_queue
#include <stack>       // stack
#include <deque>       // deque
#include <set>         // set, multiset
#include <map>         // map, multimap
#include <unordered_set>   // unordered_set
#include <unordered_map>   // unordered_map
#include <utility>     // pair, make_pair
#include <functional>  // greater, less ๋“ฑ
#include <numeric>     // accumulate, gcd, lcm
#include <cmath>       // pow, sqrt, abs ๋“ฑ
#include <climits>     // INT_MAX, LLONG_MAX ๋“ฑ
#include <cassert>     // assert ๋งคํฌ๋กœ

// ๋งŒ๋Šฅ ํ—ค๋” (๋Œ€ํšŒ์šฉ)
#include <bits/stdc++.h>  // GCC ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ๋งŒ ์ง€์›

์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋งคํฌ๋กœ

// ํƒ€์ž… ๋‹จ์ถ•
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<pii> vpii;

// ์ƒ์ˆ˜ ์ •์˜
const int INF = 1e9;
const ll LLINF = 1e18;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

// ํŽธ์˜ ๋งคํฌ๋กœ
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
#define mp make_pair
#define fi first
#define se second

// ๋ฐ˜๋ณต๋ฌธ ๋งคํฌ๋กœ
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define rrep(i, n) for(int i = (n) - 1; i >= 0; i--)

// ๋””๋ฒ„๊น… ๋งคํฌ๋กœ
#ifdef DEBUG
#define debug(x) cerr << #x << " = " << x << endl
#else
#define debug(x)
#endif

PS ํ…œํ”Œ๋ฆฟ ์˜ˆ์‹œ

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int INF = 1e9;
const int MOD = 1e9 + 7;

#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    // ์ฝ”๋“œ ์ž‘์„ฑ
    
    return 0;
}

๐Ÿšจ ํ—ค๋” ์‚ฌ์šฉ ์ฃผ์˜์‚ฌํ•ญ

  • bits/stdc++.h๋Š” GCC ์ „์šฉ (Visual Studio์—์„œ ์ž‘๋™ ์•ˆํ•จ)
  • ๋งคํฌ๋กœ ๋‚จ์šฉ ์‹œ ๋””๋ฒ„๊น… ์–ด๋ ค์›€
  • using namespace std; ์‚ฌ์šฉ ์‹œ ์ด๋ฆ„ ์ถฉ๋Œ ์ฃผ์˜
  • ๋Œ€ํšŒ๊ฐ€ ์•„๋‹Œ ์‹ค๋ฌด์—์„œ๋Š” ํ•„์š”ํ•œ ํ—ค๋”๋งŒ ํฌํ•จ

๐Ÿ“ฅ 1. ์ž…์ถœ๋ ฅ ์ฒ˜๋ฆฌ

๊ธฐ๋ณธ ์ž…๋ ฅ

#include <iostream>
#include <string>
using namespace std;

// ํ•œ ์ค„ ์ž…๋ ฅ
int n;
cin >> n;

string s;
cin >> s;  // ๊ณต๋ฐฑ ์ „๊นŒ์ง€
getline(cin, s);  // ํ•œ ์ค„ ์ „์ฒด

int a, b;
cin >> a >> b;

// ์—ฌ๋Ÿฌ ์ค„ ์ž…๋ ฅ
vector<int> arr(n);
for (int i = 0; i < n; i++) {
    cin >> arr[i];
}

// ๋ฐฐ์—ด ํ•œ๋ฒˆ์— ์ž…๋ ฅ
vector<int> numbers(n);
for (auto& x : numbers) cin >> x;

๋น ๋ฅธ ์ž…๋ ฅ (์ตœ์ ํ™”)

// ์ž…์ถœ๋ ฅ ์†๋„ ํ–ฅ์ƒ
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

// ๋ฒ„ํผ ์‚ฌ์šฉ (๋งค์šฐ ๋น ๋ฆ„)
#include <cstdio>
int n;
scanf("%d", &n);
char s[100];
scanf("%s", s);

// C++14 ์ด์ƒ์—์„œ ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ ์ž…๋ ฅ
vector<int> v(n);
for (auto& x : v) cin >> x;

์ถœ๋ ฅ ์ตœ์ ํ™”

// ๊ธฐ๋ณธ ์ถœ๋ ฅ
cout << result << '\n';  // endl๋ณด๋‹ค '\n'์ด ๋น ๋ฆ„
cout << a << ' ' << b << ' ' << c << '\n';

// ์ •๋ฐ€๋„ ์„ค์ •
cout << fixed << setprecision(10) << 3.14159265359 << '\n';

// ์—ฌ๋Ÿฌ ์ค„ ์ถœ๋ ฅ
for (int i = 0; i < n; i++) {
    cout << i << '\n';
}

// stringstream ํ™œ์šฉ (๋Œ€๋Ÿ‰ ์ถœ๋ ฅ)
stringstream ss;
for (int i = 0; i < n; i++) {
    ss << i << '\n';
}
cout << ss.str();

๐Ÿšจ ์ž…์ถœ๋ ฅ ์ฃผ์š” ํ•จ์ •

  • endl์€ ๋ฒ„ํผ๋ฅผ flushํ•˜๋ฏ€๋กœ '\n'๋ณด๋‹ค ๋А๋ฆผ
  • ios_base::sync_with_stdio(false) ์‚ฌ์šฉ ์‹œ C ์Šคํƒ€์ผ ์ž…์ถœ๋ ฅ ํ˜ผ์šฉ ๋ถˆ๊ฐ€
  • cin.ignore()๋กœ ๋ฒ„ํผ์— ๋‚จ์€ ๊ฐœํ–‰๋ฌธ์ž ์ œ๊ฑฐ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

๐Ÿ”ค 2. ๋ฌธ์ž์—ด(string) ํ•ต์‹ฌ ๋ฉ”์„œ๋“œ

๊ธฐ๋ณธ ์กฐ์ž‘

string s = "Hello World";

// ๊ธธ์ด์™€ ์ธ๋ฑ์‹ฑ
s.length();  // 11
s.size();    // 11 (๋™์ผ)
s[0];        // 'H'
s.back();    // 'd'
s.substr(1, 4);  // "ello"

// ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜
transform(s.begin(), s.end(), s.begin(), ::toupper);  // ๋Œ€๋ฌธ์ž๋กœ
transform(s.begin(), s.end(), s.begin(), ::tolower);  // ์†Œ๋ฌธ์ž๋กœ

// ๊ณต๋ฐฑ ์ฒ˜๋ฆฌ (algorithm ํ—ค๋” ํ•„์š”)
// ์™ผ์ชฝ ๊ณต๋ฐฑ ์ œ๊ฑฐ
s.erase(s.begin(), find_if(s.begin(), s.end(), [](int ch) {
    return !isspace(ch);
}));

// ์˜ค๋ฅธ์ชฝ ๊ณต๋ฐฑ ์ œ๊ฑฐ
s.erase(find_if(s.rbegin(), s.rend(), [](int ch) {
    return !isspace(ch);
}).base(), s.end());

๊ฒ€์ƒ‰๊ณผ ๋ถ„ํ• 

string s = "hello world hello";

// ๊ฒ€์ƒ‰
size_t pos = s.find("world");     // 6
if (pos != string::npos) {        // ์ฐพ์Œ
    cout << "Found at " << pos << '\n';
}
s.find("xyz");                     // string::npos (๋ชป ์ฐพ์Œ)
int count = 0;
pos = 0;
while ((pos = s.find("hello", pos)) != string::npos) {
    count++;
    pos += 5;
}

// ๋ถ„ํ• ๊ณผ ๊ฒฐํ•ฉ
vector<string> split(const string& s, char delimiter) {
    vector<string> tokens;
    stringstream ss(s);
    string token;
    while (getline(ss, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}

// ์น˜ํ™˜
size_t start_pos = 0;
while((start_pos = s.find("hello", start_pos)) != string::npos) {
    s.replace(start_pos, 5, "hi");
    start_pos += 2;
}

ํŒ๋ณ„ ๋ฉ”์„œ๋“œ

// ๋ฌธ์ž ์ข…๋ฅ˜ ํŒ๋ณ„
bool all_digits = all_of(s.begin(), s.end(), ::isdigit);
bool all_alpha = all_of(s.begin(), s.end(), ::isalpha);
bool all_alnum = all_of(s.begin(), s.end(), ::isalnum);

// ํŒจํ„ด ํŒ๋ณ„
if (s.find("he") == 0) {  // startswith
    cout << "Starts with 'he'\n";
}
if (s.size() >= 2 && s.substr(s.size() - 2) == "ld") {  // endswith
    cout << "Ends with 'ld'\n";
}

๐Ÿšจ ๋ฌธ์ž์—ด ์ฃผ์š” ํ•จ์ •

  • C++์˜ string์€ ๊ฐ€๋ณ€(mutable)
  • + ์—ฐ์‚ฐ์€ ์ƒˆ ๊ฐ์ฒด ์ƒ์„ฑ, +=๊ฐ€ ๋” ํšจ์œจ์ 
  • ๋Œ€๋Ÿ‰ ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ์‹œ stringstream ํ™œ์šฉ

๐Ÿ“‹ 3. ๋ฒกํ„ฐ(vector) ํ•ต์‹ฌ ๋ฉ”์„œ๋“œ

๊ธฐ๋ณธ ์ƒ์„ฑ๊ณผ ์กฐ์ž‘

// ์ƒ์„ฑ
vector<int> arr = {1, 2, 3, 4, 5};
vector<int> arr2(n, 0);  // ํฌ๊ธฐ n, 0์œผ๋กœ ์ดˆ๊ธฐํ™”
vector<vector<int>> matrix(n, vector<int>(m, 0));  // 2์ฐจ์› ๋ฒกํ„ฐ

// ์ถ”๊ฐ€์™€ ์‚ญ์ œ
arr.push_back(6);         // ๋์— ์ถ”๊ฐ€
arr.insert(arr.begin(), 0);  // ๋งจ ์•ž์— ์‚ฝ์ž…
arr.insert(arr.begin() + 2, 99);  // ์ธ๋ฑ์Šค 2์— ์‚ฝ์ž…

arr.pop_back();           // ๋งˆ์ง€๋ง‰ ์š”์†Œ ์ œ๊ฑฐ
arr.erase(arr.begin());   // ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ์ œ๊ฑฐ
arr.erase(arr.begin() + 2);  // ์ธ๋ฑ์Šค 2 ์ œ๊ฑฐ
arr.erase(remove(arr.begin(), arr.end(), 3), arr.end());  // ๊ฐ’ 3 ๋ชจ๋‘ ์ œ๊ฑฐ

์ •๋ ฌ๊ณผ ๊ฒ€์ƒ‰

vector<int> arr = {3, 1, 4, 1, 5};

// ์ •๋ ฌ
sort(arr.begin(), arr.end());              // ์˜ค๋ฆ„์ฐจ์ˆœ
sort(arr.begin(), arr.end(), greater<int>());  // ๋‚ด๋ฆผ์ฐจ์ˆœ

// ์ปค์Šคํ…€ ์ •๋ ฌ
sort(arr.begin(), arr.end(), [](int a, int b) {
    return a > b;  // ๋‚ด๋ฆผ์ฐจ์ˆœ
});

// ๊ฒ€์ƒ‰
auto it = find(arr.begin(), arr.end(), 4);
if (it != arr.end()) {
    int index = distance(arr.begin(), it);  // ์ธ๋ฑ์Šค ๊ตฌํ•˜๊ธฐ
}

int cnt = count(arr.begin(), arr.end(), 1);  // 1์˜ ๊ฐœ์ˆ˜

// ์ด์ง„ ํƒ์ƒ‰ (์ •๋ ฌ๋œ ๋ฒกํ„ฐ)
if (binary_search(arr.begin(), arr.end(), 4)) {
    cout << "Found\n";
}

์œ ์šฉํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

vector<int> arr = {1, 2, 3, 4, 5};

// ๋’ค์ง‘๊ธฐ
reverse(arr.begin(), arr.end());

// ํšŒ์ „
rotate(arr.begin(), arr.begin() + 2, arr.end());  // ์™ผ์ชฝ์œผ๋กœ 2์นธ

// ์ˆœ์—ด
do {
    // ํ˜„์žฌ ์ˆœ์—ด ์ฒ˜๋ฆฌ
} while (next_permutation(arr.begin(), arr.end()));

// ์ค‘๋ณต ์ œ๊ฑฐ
sort(arr.begin(), arr.end());
arr.erase(unique(arr.begin(), arr.end()), arr.end());

// ์ตœ๋Œ€/์ตœ์†Œ
auto [min_it, max_it] = minmax_element(arr.begin(), arr.end());
int min_val = *min_it;
int max_val = *max_it;

๐Ÿšจ ๋ฒกํ„ฐ ์ฃผ์š” ํ•จ์ •

  • vector<bool>์€ ํŠน์ˆ˜ํ™”๋˜์–ด ์žˆ์–ด ์ฃผ์˜ ํ•„์š”
  • push_back ์‹œ ์žฌํ• ๋‹น์œผ๋กœ ์ธํ•œ ์„ฑ๋Šฅ ์ €ํ•˜ โ†’ reserve() ํ™œ์šฉ
  • ๋ฐ˜๋ณต์ž ๋ฌดํšจํ™” ์ฃผ์˜ (์‚ฝ์ž…/์‚ญ์ œ ์‹œ)

๐Ÿ“– 4. ๋งต(map)๊ณผ ์…‹(set) ํ•ต์‹ฌ ๋ฉ”์„œ๋“œ

map ๊ธฐ๋ณธ ์กฐ์ž‘

// ์ƒ์„ฑ
map<string, int> m;
m["apple"] = 1;
m["banana"] = 2;

// ์ ‘๊ทผ๊ณผ ์ˆ˜์ •
cout << m["apple"] << '\n';  // 1
m["cherry"] = 3;              // ์ƒˆ ํ‚ค-๊ฐ’ ์ถ”๊ฐ€

// ์•ˆ์ „ํ•œ ์ ‘๊ทผ
if (m.find("grape") != m.end()) {
    cout << m["grape"] << '\n';
}

// ๋˜๋Š” C++20
if (m.contains("grape")) {
    cout << m["grape"] << '\n';
}

์กฐํšŒ์™€ ์ˆœํšŒ

map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};

// ์ˆœํšŒ (์ •๋ ฌ๋œ ์ˆœ์„œ)
for (const auto& [key, value] : m) {
    cout << key << ": " << value << '\n';
}

// ํ‚ค ์กด์žฌ ํ™•์ธ
if (m.count("a")) {  // ๋˜๋Š” m.find("a") != m.end()
    cout << "Key exists\n";
}

// ์‚ญ์ œ
m.erase("b");

unordered_map (ํ•ด์‹œ๋งต)

// O(1) ํ‰๊ท  ์‹œ๊ฐ„๋ณต์žก๋„
unordered_map<string, int> um;
um["apple"] = 1;

// ์ปค์Šคํ…€ ํ•ด์‹œ ํ•จ์ˆ˜
struct PairHash {
    size_t operator()(const pair<int, int>& p) const {
        return hash<int>()(p.first) ^ (hash<int>()(p.second) << 1);
    }
};

unordered_map<pair<int, int>, int, PairHash> coord_map;

set๊ณผ multiset

// set: ์ค‘๋ณต ์—†๋Š” ์ •๋ ฌ๋œ ์ง‘ํ•ฉ
set<int> s = {3, 1, 4, 1, 5};  // {1, 3, 4, 5}
s.insert(2);
s.erase(3);

// ๋ฒ”์œ„ ๊ฒ€์ƒ‰
auto it1 = s.lower_bound(2);  // 2 ์ด์ƒ์ธ ์ฒซ ์›์†Œ
auto it2 = s.upper_bound(4);  // 4 ์ดˆ๊ณผ์ธ ์ฒซ ์›์†Œ

// multiset: ์ค‘๋ณต ํ—ˆ์šฉ
multiset<int> ms = {1, 2, 2, 3, 3, 3};
cout << ms.count(3) << '\n';  // 3

๐Ÿšจ map/set ์ฃผ์š” ํ•จ์ •

  • map์€ ์ž๋™ ์ •๋ ฌ (O(log n) ์—ฐ์‚ฐ)
  • unordered_map์€ ํ•ด์‹œ ์ถฉ๋Œ ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜
  • [] ์—ฐ์‚ฐ์ž๋Š” ์—†๋Š” ํ‚ค ์ ‘๊ทผ ์‹œ ์ž๋™ ์ƒ์„ฑ

๐Ÿ”ข 5. ๊ธฐํƒ€ STL ์ปจํ…Œ์ด๋„ˆ

queue์™€ priority_queue

// ์ผ๋ฐ˜ ํ
queue<int> q;
q.push(1);
q.push(2);
cout << q.front() << '\n';  // 1
q.pop();

// ์šฐ์„ ์ˆœ์œ„ ํ (์ตœ๋Œ€ ํž™)
priority_queue<int> pq;
pq.push(3);
pq.push(1);
pq.push(4);
cout << pq.top() << '\n';  // 4

// ์ตœ์†Œ ํž™
priority_queue<int, vector<int>, greater<int>> min_pq;

// ์ปค์Šคํ…€ ๋น„๊ต
struct Compare {
    bool operator()(const pair<int, int>& a, const pair<int, int>& b) {
        return a.second > b.second;  // second ๊ธฐ์ค€ ์ตœ์†Œ ํž™
    }
};
priority_queue<pair<int, int>, vector<pair<int, int>>, Compare> custom_pq;

stack๊ณผ deque

// ์Šคํƒ
stack<int> st;
st.push(1);
st.push(2);
cout << st.top() << '\n';  // 2
st.pop();

// ๋ฑ (์–‘๋ฐฉํ–ฅ ํ)
deque<int> dq;
dq.push_back(1);
dq.push_front(0);
dq.pop_back();
dq.pop_front();

๐Ÿ”„ 6. ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ ๊ณ ๊ธ‰ ํ™œ์šฉ

์กฐ๊ฑด๋ฌธ ์ตœ์ ํ™”

// ์‚ผํ•ญ ์—ฐ์‚ฐ์ž
int result = condition ? value_if_true : value_if_false;

// switch ๋ฌธ
switch (value) {
    case 1:
        // ์ฒ˜๋ฆฌ
        break;
    case 2:
    case 3:  // ์—ฌ๋Ÿฌ ์ผ€์ด์Šค
        // ์ฒ˜๋ฆฌ
        break;
    default:
        // ๊ธฐ๋ณธ ์ฒ˜๋ฆฌ
}

// C++17 if๋ฌธ ์ดˆ๊ธฐํ™”
if (auto it = m.find(key); it != m.end()) {
    // it ์‚ฌ์šฉ
}

๋ฐ˜๋ณต๋ฌธ ํŒจํ„ด

// ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ for๋ฌธ
vector<int> v = {1, 2, 3, 4, 5};
for (const auto& x : v) {
    cout << x << ' ';
}

// ์ธ๋ฑ์Šค์™€ ํ•จ๊ป˜
for (int i = 0; i < v.size(); i++) {
    cout << i << ": " << v[i] << '\n';
}

// ์—ญ์ˆœ ๋ฐ˜๋ณต
for (int i = n - 1; i >= 0; i--) {
    // ์ฒ˜๋ฆฌ
}

// iterator ํ™œ์šฉ
for (auto it = v.begin(); it != v.end(); ++it) {
    cout << *it << ' ';
}

โšก 7. ํ•จ์ˆ˜์™€ ๋žŒ๋‹ค ํ‘œํ˜„์‹

ํ•จ์ˆ˜ ์ •์˜์™€ ํ™œ์šฉ

// ๊ธฐ๋ณธ ํ•จ์ˆ˜
int gcd(int a, int b) {
    while (b) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// ๊ธฐ๋ณธ๊ฐ’ ๋งค๊ฐœ๋ณ€์ˆ˜
int power(int base, int exp = 2) {
    return pow(base, exp);
}

// ํ…œํ”Œ๋ฆฟ ํ•จ์ˆ˜
template<typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

// ๊ฐ€๋ณ€ ์ธ์ž (C++11)
template<typename... Args>
void print(Args... args) {
    ((cout << args << ' '), ...);
    cout << '\n';
}

๋žŒ๋‹ค ํ‘œํ˜„์‹

// ๊ธฐ๋ณธ ๋žŒ๋‹ค
auto square = [](int x) { return x * x; };
auto add = [](int x, int y) { return x + y; };

// ์ •๋ ฌ์—์„œ ๋žŒ๋‹ค ํ™œ์šฉ
vector<pair<string, int>> students = {{"Alice", 85}, {"Bob", 90}, {"Charlie", 78}};
sort(students.begin(), students.end(), [](const auto& a, const auto& b) {
    return a.second > b.second;  // ์ ์ˆ˜ ๋‚ด๋ฆผ์ฐจ์ˆœ
});

// ์บก์ฒ˜
int factor = 10;
auto multiply = [factor](int x) { return x * factor; };

// STL ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ํ•จ๊ป˜
vector<int> numbers = {1, 2, 3, 4, 5};
transform(numbers.begin(), numbers.end(), numbers.begin(), 
          [](int x) { return x * x; });

vector<int> evens;
copy_if(numbers.begin(), numbers.end(), back_inserter(evens),
        [](int x) { return x % 2 == 0; });

STL Algorithm ํ•ต์‹ฌ ํ•จ์ˆ˜๋“ค

๊ฒ€์ƒ‰๊ณผ ์กฐ๊ฑด ํ™•์ธ

vector<int> v = {1, 2, 3, 4, 5, 2, 3};

// ๊ฒ€์ƒ‰ ํ•จ์ˆ˜๋“ค
auto it = find(v.begin(), v.end(), 3);           // ์ฒซ ๋ฒˆ์งธ 3์˜ ์œ„์น˜
if (it != v.end()) {
    cout << "Found at index: " << it - v.begin() << '\n';
}

auto it2 = find_if(v.begin(), v.end(), [](int x) { return x > 3; });  // ์กฐ๊ฑด ๋งŒ์กฑํ•˜๋Š” ์ฒซ ์›์†Œ
int cnt = count(v.begin(), v.end(), 2);          // 2์˜ ๊ฐœ์ˆ˜
int cnt_if = count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });  // ์ง์ˆ˜ ๊ฐœ์ˆ˜

// ์ด์ง„ ํƒ์ƒ‰ (์ •๋ ฌ๋œ ๋ฐฐ์—ด ํ•„์š”)
sort(v.begin(), v.end());
bool found = binary_search(v.begin(), v.end(), 3);
auto lb = lower_bound(v.begin(), v.end(), 3);   // 3 ์ด์ƒ์ธ ์ฒซ ์œ„์น˜
auto ub = upper_bound(v.begin(), v.end(), 3);   // 3 ์ดˆ๊ณผ์ธ ์ฒซ ์œ„์น˜

// ์กฐ๊ฑด ํ™•์ธ
bool all_positive = all_of(v.begin(), v.end(), [](int x) { return x > 0; });
bool any_even = any_of(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
bool none_negative = none_of(v.begin(), v.end(), [](int x) { return x < 0; });

๋ณ€ํ™˜๊ณผ ์ƒ์„ฑ

vector<int> v = {1, 2, 3, 4, 5};
vector<int> squares;

// transform: ๊ฐ ์›์†Œ์— ํ•จ์ˆ˜ ์ ์šฉ
transform(v.begin(), v.end(), back_inserter(squares), 
          [](int x) { return x * x; });

// generate: ํ•จ์ˆ˜๋กœ ๊ฐ’ ์ƒ์„ฑ
vector<int> random_nums(10);
generate(random_nums.begin(), random_nums.end(), []() { return rand() % 100; });

// iota: ์—ฐ์†๋œ ๊ฐ’์œผ๋กœ ์ฑ„์šฐ๊ธฐ (C++11)
vector<int> sequence(10);
iota(sequence.begin(), sequence.end(), 1);  // {1, 2, 3, ..., 10}

// fill: ๊ฐ™์€ ๊ฐ’์œผ๋กœ ์ฑ„์šฐ๊ธฐ
fill(v.begin(), v.end(), 42);

์ˆ˜์น˜ ์—ฐ์‚ฐ

vector<int> v = {1, 2, 3, 4, 5};

// accumulate: ๋ˆ„์  ์—ฐ์‚ฐ
int sum = accumulate(v.begin(), v.end(), 0);
int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());

// ์ธ์ ‘ํ•œ ์ฐจ์ด ๊ณ„์‚ฐ
vector<int> differences;
adjacent_difference(v.begin(), v.end(), back_inserter(differences));

// ๋ถ€๋ถ„ํ•ฉ ๊ณ„์‚ฐ
vector<int> partial_sums;
partial_sum(v.begin(), v.end(), back_inserter(partial_sums));

// GCD์™€ LCM (C++17)
int gcd_val = gcd(12, 8);  // 4
int lcm_val = lcm(12, 8);  // 24

// ์ˆ˜ํ•™ ํ•จ์ˆ˜๋“ค
abs(-5);           // 5
min(1, 2);         // 1
max({1, 2, 3});    // 3 (initializer_list)

์ˆœ์—ด๊ณผ ์กฐํ•ฉ

vector<int> v = {1, 2, 3, 4};

// ๋‹ค์Œ/์ด์ „ ์ˆœ์—ด
do {
    // ํ˜„์žฌ ์ˆœ์—ด ์ฒ˜๋ฆฌ
    for (int x : v) cout << x << ' ';
    cout << '\n';
} while (next_permutation(v.begin(), v.end()));

// ์ด์ „ ์ˆœ์—ด๋„ ๊ฐ€๋Šฅ
while (prev_permutation(v.begin(), v.end())) {
    // ์ฒ˜๋ฆฌ
}

// ํŠน์ • ์œ„์น˜ ์š”์†Œ๋“ค
nth_element(v.begin(), v.begin() + 2, v.end());  // 3๋ฒˆ์งธ๋กœ ์ž‘์€ ์›์†Œ๋ฅผ ์ธ๋ฑ์Šค 2์— ๋ฐฐ์น˜

์ง‘ํ•ฉ ์—ฐ์‚ฐ

vector<int> a = {1, 2, 3, 4, 5};
vector<int> b = {3, 4, 5, 6, 7};
vector<int> result;

// ์ •๋ ฌ๋œ ๋ฒกํ„ฐ ๊ฐ„ ์ง‘ํ•ฉ ์—ฐ์‚ฐ
set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(result));
result.clear();

set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(result));
result.clear();

set_difference(a.begin(), a.end(), b.begin(), b.end(), back_inserter(result));

// ํฌํ•จ ๊ด€๊ณ„ ํ™•์ธ
bool is_subset = includes(a.begin(), a.end(), b.begin(), b.end());

๊ตฌ์กฐ ๋ณ€๊ฒฝ

vector<int> v = {1, 2, 3, 4, 5, 2, 1};

// ๋’ค์ง‘๊ธฐ
reverse(v.begin(), v.end());

// ํšŒ์ „
rotate(v.begin(), v.begin() + 2, v.end());  // ์™ผ์ชฝ์œผ๋กœ 2์นธ ํšŒ์ „

// ์ค‘๋ณต ์ œ๊ฑฐ (์ •๋ ฌ ํ›„)
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());

// ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๋ถ„ํ• 
partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });  // ์ง์ˆ˜๋ฅผ ์•ž์œผ๋กœ

// ์กฐ๊ฑด ๋งŒ์กฑํ•˜๋Š” ์›์†Œ ๋ณต์‚ฌ
vector<int> evens;
copy_if(v.begin(), v.end(), back_inserter(evens), [](int x) { return x % 2 == 0; });

// ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ์ œ๊ฑฐ
v.erase(remove_if(v.begin(), v.end(), [](int x) { return x < 0; }), v.end());

์ตœ๋Œ€/์ตœ์†Œ ์ฐพ๊ธฐ

vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

// ๋‹จ์ผ ์›์†Œ
auto min_it = min_element(v.begin(), v.end());
auto max_it = max_element(v.begin(), v.end());

// ๋™์‹œ์— ์ฐพ๊ธฐ (C++11)
auto [min_it2, max_it2] = minmax_element(v.begin(), v.end());

// ๊ฐ’ ๋น„๊ต
int min_val = min({3, 1, 4, 1, 5});
int max_val = max({3, 1, 4, 1, 5});

๐Ÿšจ STL Algorithm ์ฃผ์š” ํ•จ์ •

  • ๋Œ€๋ถ€๋ถ„์˜ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋ณต์ž ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉ (๋งˆ์ง€๋ง‰์€ exclusive)
  • ์ด์ง„ ํƒ์ƒ‰ ํ•จ์ˆ˜๋“ค์€ ์ •๋ ฌ๋œ ๋ฒ”์œ„ ํ•„์š”
  • remove๋Š” ์‹ค์ œ๋กœ ์‚ญ์ œํ•˜์ง€ ์•Š์Œ, erase์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
  • unique๋Š” ์ธ์ ‘ํ•œ ์ค‘๋ณต๋งŒ ์ œ๊ฑฐ, ์ •๋ ฌ ํ›„ ์‚ฌ์šฉ
  • ๋žŒ๋‹ค ํ•จ์ˆ˜ ํ™œ์šฉ์œผ๋กœ ์œ ์—ฐํ•œ ์กฐ๊ฑด ์ง€์ •

๐Ÿ›ก๏ธ 8. ์˜ˆ์™ธ์ฒ˜๋ฆฌ์™€ ๋””๋ฒ„๊น…

๊ธฐ๋ณธ ์˜ˆ์™ธ์ฒ˜๋ฆฌ

try {
    int result = 10 / 0;  // ์‹ค์ œ๋กœ๋Š” ์ •์ˆ˜ ๋‚˜๋ˆ—์…ˆ์€ ์˜ˆ์™ธ ๋ฐœ์ƒ ์•ˆํ•จ
} catch (const exception& e) {
    cerr << "Error: " << e.what() << '\n';
}

// ์‚ฌ์šฉ์ž ์ •์˜ ์˜ˆ์™ธ
class CustomException : public exception {
    const char* what() const noexcept override {
        return "Custom error occurred";
    }
};

๋””๋ฒ„๊น… ๊ธฐ๋ฒ•

// assert ๋งคํฌ๋กœ
#include <cassert>
assert(n > 0);  // ์กฐ๊ฑด์ด false๋ฉด ํ”„๋กœ๊ทธ๋žจ ์ค‘๋‹จ

// ๋””๋ฒ„๊ทธ ์ถœ๋ ฅ
#ifdef DEBUG
    #define debug(x) cerr << #x << " = " << x << '\n'
#else
    #define debug(x)
#endif

// ์‚ฌ์šฉ
int value = 42;
debug(value);  // DEBUG ์ •์˜์‹œ: value = 42 ์ถœ๋ ฅ

๐Ÿ“ 1๋‹จ๊ณ„ ํ•ต์‹ฌ ์š”์•ฝ

๊ผญ ๊ธฐ์–ตํ•ด์•ผ ํ•  ํŒจํ„ด

  1. ๋น ๋ฅธ ์ž…์ถœ๋ ฅ: ios_base::sync_with_stdio(false)์™€ '\n'
  2. ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ: substr(), find(), stringstream
  3. ๋ฒกํ„ฐ ์กฐ์ž‘: sort(), unique(), ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ for๋ฌธ
  4. ๋งต/์…‹: find(), count(), unordered ๋ฒ„์ „
  5. STL ์•Œ๊ณ ๋ฆฌ์ฆ˜: accumulate(), transform(), copy_if()
  6. ๋žŒ๋‹ค ํ‘œํ˜„์‹: ์ •๋ ฌ๊ณผ STL ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ํ™œ์šฉ

์ž์ฃผ ํ•˜๋Š” ์‹ค์ˆ˜๋“ค

  • endl ๋Œ€์‹  ‘\n’ ์‚ฌ์šฉ
  • ๋ฒกํ„ฐ ํฌ๊ธฐ ๋ฏธ๋ฆฌ ์˜ˆ์•ฝ (reserve())
  • map์˜ [] ์—ฐ์‚ฐ์ž ์ž๋™ ์ƒ์„ฑ ์ฃผ์˜
  • iterator ๋ฌดํšจํ™” ์ฃผ์˜
  • ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ํ˜• ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ

C++ PS 2๋‹จ๊ณ„: ๋‹ค๋ฅธ ์–ธ์–ด ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ C++ ํŠนํ™” ๊ธฐ๋ฒ•

๐Ÿ”€ 1. ๋ถ„๊ธฐ๋ฌธ๊ณผ ์ œ์–ด๋ฌธ - C++๋งŒ์˜ ํŠน์ง•

์กฐ๊ฑด๋ฌธ์˜ C++์Šค๋Ÿฌ์šด ํ‘œํ˜„

์‚ผํ•ญ ์—ฐ์‚ฐ์ž (Ternary Operator)

// ๊ธฐ๋ณธ ํ˜•ํƒœ
int result = condition ? value_if_true : value_if_false;

// ์‹ค์šฉ ์˜ˆ์‹œ
int max_val = (a > b) ? a : b;
string status = (score >= 60) ? "pass" : "fail";
int sign = (num >= 0) ? 1 : -1;

// ์ค‘์ฒฉ ์‚ผํ•ญ ์—ฐ์‚ฐ์ž (๊ฐ€๋…์„ฑ ์ฃผ์˜)
char grade = (score >= 90) ? 'A' : (score >= 80) ? 'B' : 'C';

// Python๊ณผ ๋‹ค๋ฅธ ์ : C++๋Š” ์ „ํ†ต์ ์ธ ? : ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
// Python: result = value1 if condition else value2
// C++: int result = condition ? value1 : value2;

์กฐ๊ฑด ํ‰๊ฐ€์™€ ๋‹จ๋ฝ ํ‰๊ฐ€ (Short-circuit Evaluation)

// C++์—์„œ false๋กœ ํ‰๊ฐ€๋˜๋Š” ๊ฐ’๋“ค
// 0, nullptr, false๋งŒ false (Python๊ณผ ๋‹ค๋ฆ„)

// ๋‹จ๋ฝ ํ‰๊ฐ€ ํ™œ์šฉ
if (ptr != nullptr && ptr->value > 0) {
    // ptr์ด null์ด๋ฉด ๋’ค๋Š” ํ‰๊ฐ€ํ•˜์ง€ ์•Š์Œ
}

// ๊ธฐ๋ณธ๊ฐ’ ์„ค์ • ํŒจํ„ด
string name = input_name.empty() ? "Anonymous" : input_name;

// Python๊ณผ ๋‹ค๋ฅธ ์ : ๋นˆ ์ปจํ…Œ์ด๋„ˆ๋„ true
vector<int> v;
if (v.empty()) {  // ๋ช…์‹œ์ ์œผ๋กœ empty() ์ฒดํฌ ํ•„์š”
    cout << "Empty vector\n";
}

constexpr if (C++17)

template<typename T>
void process(T value) {
    if constexpr (is_integral_v<T>) {
        cout << "Integer: " << value << '\n';
    } else if constexpr (is_floating_point_v<T>) {
        cout << "Float: " << fixed << setprecision(2) << value << '\n';
    } else {
        cout << "Other type\n";
    }
}

// ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ถ„๊ธฐ ๊ฒฐ์ •
template<int N>
void print() {
    if constexpr (N > 10) {
        cout << "Large number\n";
    } else {
        cout << "Small number\n";
    }
}

switch ๋ฌธ์˜ ๊ณ ๊ธ‰ ํ™œ์šฉ

// ๊ธฐ๋ณธ switch
switch (status) {
    case 200:
        return "OK";
    case 404:
        return "Not Found";
    case 500:
    case 502:
    case 503:  // ์—ฌ๋Ÿฌ ๊ฐ’ ๋งค์นญ
        return "Server Error";
    default:
        return "Unknown Status";
}

// C++17 switch with initialization
switch (auto val = calculate(); val) {
    case 1:
        // val ์‚ฌ์šฉ ๊ฐ€๋Šฅ
        break;
    case 2:
        break;
}

// enum class์™€ switch
enum class Color { Red, Green, Blue };

Color c = Color::Red;
switch (c) {
    case Color::Red:
        cout << "Red\n";
        break;
    case Color::Green:
        cout << "Green\n";
        break;
    case Color::Blue:
        cout << "Blue\n";
        break;
}

๐Ÿ”„ 2. ๋ฐ˜๋ณต๋ฌธ - C++์˜ ๊ฐ•๋ ฅํ•œ ์ดํ„ฐ๋ ˆ์ด์…˜

๋ฒ”์œ„ ๊ธฐ๋ฐ˜ for๋ฌธ (Range-based for loop)

// ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•
vector<int> v = {1, 2, 3, 4, 5};
for (int x : v) {
    cout << x << ' ';
}

// ์ฐธ์กฐ๋กœ ๋ฐ›๊ธฐ (๋ณต์‚ฌ ๋ฐฉ์ง€)
for (const auto& x : v) {
    cout << x << ' ';
}

// ์ˆ˜์ •ํ•˜๋ ค๋ฉด ๋น„const ์ฐธ์กฐ
for (auto& x : v) {
    x *= 2;
}

// ๊ตฌ์กฐํ™” ๋ฐ”์ธ๋”ฉ (C++17)
map<string, int> m = {{"Alice", 25}, {"Bob", 30}};
for (const auto& [name, age] : m) {
    cout << name << " is " << age << " years old\n";
}

// ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ
for (int x : {1, 2, 3, 4, 5}) {
    cout << x << ' ';
}

์ „ํ†ต์ ์ธ for๋ฌธ์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ

// ์ธ๋ฑ์Šค์™€ ํ•จ๊ป˜
for (size_t i = 0; i < v.size(); ++i) {
    cout << i << ": " << v[i] << '\n';
}

// ์—ญ์ˆœ ๋ฐ˜๋ณต (๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ ์ฃผ์˜)
for (int i = n - 1; i >= 0; --i) {
    cout << v[i] << ' ';
}

// ๋˜๋Š” size_t ์‚ฌ์šฉ์‹œ
for (size_t i = n; i-- > 0; ) {
    cout << v[i] << ' ';
}

// 2์ฐจ์› ๋ฐฐ์—ด ์ˆœํšŒ
int matrix[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
        cout << matrix[i][j] << ' ';
    }
    cout << '\n';
}

// ๋” C++์Šค๋Ÿฌ์šด ๋ฐฉ๋ฒ•
for (const auto& row : matrix) {
    for (int cell : row) {
        cout << cell << ' ';
    }
    cout << '\n';
}

๋ฐ˜๋ณต์ž(Iterator) ํ™œ์šฉ

// ๊ธฐ๋ณธ ๋ฐ˜๋ณต์ž
vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end(); ++it) {
    cout << *it << ' ';
}

// ์—ญ๋ฐฉํ–ฅ ๋ฐ˜๋ณต์ž
for (auto it = v.rbegin(); it != v.rend(); ++it) {
    cout << *it << ' ';
}

// ๋ฐ˜๋ณต์ž ์‚ฐ์ˆ 
auto mid = v.begin() + v.size() / 2;
cout << "Middle element: " << *mid << '\n';

// ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ
auto pos = find(v.begin(), v.end(), 3);
if (pos != v.end()) {
    cout << "Found at index: " << distance(v.begin(), pos) << '\n';
}

// ๋ฐ˜๋ณต์ž ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ํ™œ์šฉ
// Random Access Iterator (vector, deque)
sort(v.begin(), v.end());

// Bidirectional Iterator (list, set, map)
list<int> lst = {1, 2, 3, 4, 5};
reverse(lst.begin(), lst.end());

๐Ÿฌ 3. ํ…œํ”Œ๋ฆฟ๊ณผ ์ œ๋„ค๋ฆญ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ

// ๊ธฐ๋ณธ ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ
template<typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

// ์—ฌ๋Ÿฌ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

// C++14 ์ดํ›„ (auto ๋ฐ˜ํ™˜ ํƒ€์ž…)
template<typename T, typename U>
auto add(T a, U b) {
    return a + b;
}

// ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™”
template<>
string getMax<string>(string a, string b) {
    return (a.length() > b.length()) ? a : b;
}

// ๊ฐ€๋ณ€ ํ…œํ”Œ๋ฆฟ (C++11)
template<typename... Args>
void print(Args... args) {
    ((cout << args << ' '), ...);  // C++17 fold expression
    cout << '\n';
}

ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ

// ๊ธฐ๋ณธ ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ
template<typename T>
class Stack {
private:
    vector<T> elements;
public:
    void push(const T& elem) {
        elements.push_back(elem);
    }
    
    T pop() {
        T elem = elements.back();
        elements.pop_back();
        return elem;
    }
    
    bool empty() const {
        return elements.empty();
    }
};

// ์‚ฌ์šฉ
Stack<int> intStack;
Stack<string> stringStack;

// ํ…œํ”Œ๋ฆฟ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ถ”๋ก  (C++17)
Stack s{1, 2, 3};  // Stack<int>๋กœ ์ถ”๋ก 

SFINAE์™€ enable_if

// ์ •์ˆ˜ ํƒ€์ž…๋งŒ ํ—ˆ์šฉํ•˜๋Š” ํ•จ์ˆ˜
template<typename T>
typename enable_if<is_integral<T>::value, T>::type
sum(T a, T b) {
    return a + b;
}

// C++17 if constexpr๋กœ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ
template<typename T>
T process(T value) {
    if constexpr (is_integral_v<T>) {
        return value * 2;
    } else if constexpr (is_floating_point_v<T>) {
        return value / 2.0;
    } else {
        return value;
    }
}

// Concepts (C++20)
template<typename T>
concept Numeric = is_arithmetic_v<T>;

template<Numeric T>
T multiply(T a, T b) {
    return a * b;
}

๐Ÿ 4. C++ ํŠน์ง•์ ์ธ ๋ถ€๋ถ„๋“ค

ํฌ์ธํ„ฐ์™€ ์ฐธ์กฐ

// ํฌ์ธํ„ฐ
int x = 5;
int* ptr = &x;
cout << *ptr << '\n';  // 5

// ๋„ ํฌ์ธํ„ฐ
int* p = nullptr;  // C++11, NULL ๋Œ€์‹  ์‚ฌ์šฉ

// ์ฐธ์กฐ
int& ref = x;
ref = 10;  // x๋„ 10์ด ๋จ

// const ์ฐธ์กฐ (์ž„์‹œ ๊ฐ์ฒด ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅ)
const int& cref = 42;

// ํฌ์ธํ„ฐ vs ์ฐธ์กฐ
void by_pointer(int* p) {
    if (p) *p = 10;
}

void by_reference(int& r) {
    r = 10;  // ๋„ ์ฒดํฌ ๋ถˆํ•„์š”
}

// ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ (C++11)
unique_ptr<int> up = make_unique<int>(42);
shared_ptr<int> sp = make_shared<int>(42);
weak_ptr<int> wp = sp;

์ด๋™ ์˜๋ฏธ๋ก  (Move Semantics)

// ์ด๋™ ์ƒ์„ฑ์ž์™€ ์ด๋™ ๋Œ€์ž…
class Buffer {
    char* data;
    size_t size;
public:
    // ์ด๋™ ์ƒ์„ฑ์ž
    Buffer(Buffer&& other) noexcept 
        : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
    }
    
    // ์ด๋™ ๋Œ€์ž… ์—ฐ์‚ฐ์ž
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            size = other.size;
            other.data = nullptr;
            other.size = 0;
        }
        return *this;
    }
};

// std::move ํ™œ์šฉ
vector<string> v1 = {"hello", "world"};
vector<string> v2 = move(v1);  // v1์˜ ๋‚ด์šฉ์ด v2๋กœ ์ด๋™

// ์™„๋ฒฝํ•œ ์ „๋‹ฌ (Perfect Forwarding)
template<typename T>
void wrapper(T&& arg) {
    process(forward<T>(arg));
}

RAII์™€ ์Šค์ฝ”ํ”„ ๊ฐ€๋“œ

// RAII (Resource Acquisition Is Initialization)
class FileHandler {
    FILE* file;
public:
    FileHandler(const char* filename) {
        file = fopen(filename, "r");
    }
    ~FileHandler() {
        if (file) fclose(file);
    }
    // ๋ณต์‚ฌ ๊ธˆ์ง€
    FileHandler(const FileHandler&) = delete;
    FileHandler& operator=(const FileHandler&) = delete;
};

// ์Šค์ฝ”ํ”„ ๊ฐ€๋“œ ํŒจํ„ด
class ScopeGuard {
    function<void()> onExit;
public:
    ScopeGuard(function<void()> f) : onExit(f) {}
    ~ScopeGuard() { onExit(); }
};

// ์‚ฌ์šฉ
{
    ScopeGuard guard([]{ cout << "Exiting scope\n"; });
    // ์ž‘์—… ์ˆ˜ํ–‰
}  // ์ž๋™์œผ๋กœ "Exiting scope" ์ถœ๋ ฅ

constexpr๊ณผ ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ณ„์‚ฐ

// constexpr ํ•จ์ˆ˜
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

// ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ณ„์‚ฐ
constexpr int fact5 = factorial(5);  // 120

// constexpr ๋ณ€์ˆ˜
constexpr double pi = 3.14159265359;
constexpr int arr_size = 100;
int arr[arr_size];  // ๊ฐ€๋Šฅ

// C++14 constexpr ํ™•์žฅ
constexpr int fibonacci(int n) {
    if (n <= 1) return n;
    int prev = 0, curr = 1;
    for (int i = 2; i <= n; ++i) {
        int next = prev + curr;
        prev = curr;
        curr = next;
    }
    return curr;
}

๐Ÿ”ง 5. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋žŒ๋‹ค

๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ๊ณ ๊ธ‰ ํ™œ์šฉ

// ๊ธฐ๋ณธ ๋žŒ๋‹ค
auto square = [](int x) { return x * x; };
auto add = [](int x, int y) { return x + y; };

// ์บก์ฒ˜ ๋ชจ๋“œ
int a = 1, b = 2;
auto f1 = [a, b]() { return a + b; };      // ๊ฐ’ ์บก์ฒ˜
auto f2 = [&a, &b]() { return a + b; };    // ์ฐธ์กฐ ์บก์ฒ˜
auto f3 = [=]() { return a + b; };         // ๋ชจ๋“  ๋ณ€์ˆ˜ ๊ฐ’ ์บก์ฒ˜
auto f4 = [&]() { return a + b; };         // ๋ชจ๋“  ๋ณ€์ˆ˜ ์ฐธ์กฐ ์บก์ฒ˜
auto f5 = [=, &b]() { return a + b; };     // a๋Š” ๊ฐ’, b๋Š” ์ฐธ์กฐ

// mutable ๋žŒ๋‹ค
auto counter = [count = 0]() mutable {
    return ++count;
};

// ์ œ๋„ค๋ฆญ ๋žŒ๋‹ค (C++14)
auto generic_add = [](auto a, auto b) {
    return a + b;
};

// ์žฌ๊ท€ ๋žŒ๋‹ค
function<int(int)> fib = [&fib](int n) {
    return (n <= 1) ? n : fib(n-1) + fib(n-2);
};

STL ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

vector<int> v = {1, 2, 3, 4, 5};

// transform: ๋ชจ๋“  ์š”์†Œ์— ํ•จ์ˆ˜ ์ ์šฉ
vector<int> squares;
transform(v.begin(), v.end(), back_inserter(squares),
          [](int x) { return x * x; });

// accumulate: ๋ˆ„์  ์—ฐ์‚ฐ
int sum = accumulate(v.begin(), v.end(), 0);
int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());

// partition: ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋ถ„ํ• 
partition(v.begin(), v.end(), [](int x) { return x % 2 == 0; });

// all_of, any_of, none_of
bool all_positive = all_of(v.begin(), v.end(), [](int x) { return x > 0; });
bool has_even = any_of(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
bool no_negative = none_of(v.begin(), v.end(), [](int x) { return x < 0; });

// ํ•จ์ˆ˜ ํ•ฉ์„ฑ
auto compose = [](auto f, auto g) {
    return [=](auto x) { return f(g(x)); };
};

auto add_one = [](int x) { return x + 1; };
auto double_it = [](int x) { return x * 2; };
auto add_one_then_double = compose(double_it, add_one);

std::function๊ณผ ํ•จ์ˆ˜ ๊ฐ์ฒด

// std::function
function<int(int, int)> operation;
operation = add;
cout << operation(5, 3) << '\n';  // 8

operation = [](int a, int b) { return a * b; };
cout << operation(5, 3) << '\n';  // 15

// ํ•จ์ˆ˜ ๊ฐ์ฒด (Functor)
struct Multiplier {
    int factor;
    Multiplier(int f) : factor(f) {}
    int operator()(int x) const {
        return x * factor;
    }
};

Multiplier times3(3);
cout << times3(5) << '\n';  // 15

// STL ํ•จ์ˆ˜ ๊ฐ์ฒด
vector<int> v = {3, 1, 4, 1, 5};
sort(v.begin(), v.end(), greater<int>());  // ๋‚ด๋ฆผ์ฐจ์ˆœ

๐Ÿ“Š 6. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์™€ ์ตœ์ ํ™”

๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น

// ๊ธฐ๋ณธ new/delete
int* p = new int(42);
delete p;

int* arr = new int[10];
delete[] arr;

// placement new
char buffer[sizeof(string)];
string* ps = new (buffer) string("Hello");
ps->~string();  // ๋ช…์‹œ์  ์†Œ๋ฉธ์ž ํ˜ธ์ถœ

// nothrow new
int* p = new(nothrow) int[1000000000];
if (!p) {
    cout << "Allocation failed\n";
}

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ํ™œ์šฉ

// unique_ptr: ๋‹จ๋… ์†Œ์œ ๊ถŒ
unique_ptr<int> up1 = make_unique<int>(42);
unique_ptr<int> up2 = move(up1);  // ์†Œ์œ ๊ถŒ ์ด์ „

// shared_ptr: ๊ณต์œ  ์†Œ์œ ๊ถŒ
shared_ptr<int> sp1 = make_shared<int>(42);
shared_ptr<int> sp2 = sp1;  // ์ฐธ์กฐ ์นด์šดํŠธ ์ฆ๊ฐ€
cout << sp1.use_count() << '\n';  // 2

// weak_ptr: ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€
shared_ptr<Node> node1 = make_shared<Node>();
shared_ptr<Node> node2 = make_shared<Node>();
node1->next = node2;
node2->prev = weak_ptr<Node>(node1);  // ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€

// ์ปค์Šคํ…€ ์‚ญ์ œ์ž
auto deleter = [](FILE* f) { fclose(f); };
unique_ptr<FILE, decltype(deleter)> file(fopen("data.txt", "r"), deleter);

๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™” ๊ธฐ๋ฒ•

// ๋ฉ”๋ชจ๋ฆฌ ํ’€
template<typename T>
class MemoryPool {
    vector<T> pool;
    stack<T*> available;
public:
    T* allocate() {
        if (available.empty()) {
            pool.emplace_back();
            return &pool.back();
        }
        T* ptr = available.top();
        available.pop();
        return ptr;
    }
    
    void deallocate(T* ptr) {
        available.push(ptr);
    }
};

// ์ž‘์€ ๋ฌธ์ž์—ด ์ตœ์ ํ™” (SSO)
// std::string์€ ์ด๋ฏธ SSO ๊ตฌํ˜„

// ๋ฉ”๋ชจ๋ฆฌ ์ •๋ ฌ
struct alignas(64) CacheLinePadded {
    int data;
    // ์บ์‹œ ๋ผ์ธ ํฌ๊ธฐ๋กœ ์ •๋ ฌ
};

// reserve๋ฅผ ํ†ตํ•œ ์žฌํ• ๋‹น ๋ฐฉ์ง€
vector<int> v;
v.reserve(1000);  // ๋ฏธ๋ฆฌ ๊ณต๊ฐ„ ํ• ๋‹น
for (int i = 0; i < 1000; ++i) {
    v.push_back(i);  // ์žฌํ• ๋‹น ์—†์Œ
}

๐ŸŽฏ 7. ์‹ค์ „ ํ™œ์šฉ ํŒจํ„ด ๋ชจ์Œ

๋น„ํŠธ ์—ฐ์‚ฐ ์ตœ์ ํ™”

// ๋น„ํŠธ ํ”Œ๋ž˜๊ทธ
enum Flags {
    FLAG_A = 1 << 0,  // 1
    FLAG_B = 1 << 1,  // 2
    FLAG_C = 1 << 2   // 4
};

int flags = FLAG_A | FLAG_C;  // ํ”Œ๋ž˜๊ทธ ์„ค์ •
if (flags & FLAG_A) {  // ํ”Œ๋ž˜๊ทธ ํ™•์ธ
    cout << "Flag A is set\n";
}
flags &= ~FLAG_A;  // ํ”Œ๋ž˜๊ทธ ํ•ด์ œ

// ๋น„ํŠธ ์นด์šดํŠธ
int popcount(unsigned int n) {
    return __builtin_popcount(n);  // GCC/Clang
}

// ์ตœํ•˜์œ„ ๋น„ํŠธ
int lowest_bit(int n) {
    return n & -n;
}

// ๋น„ํŠธ ์ˆœํšŒ
for (int subset = mask; subset; subset = (subset - 1) & mask) {
    // mask์˜ ๋ชจ๋“  ๋ถ€๋ถ„์ง‘ํ•ฉ ์ˆœํšŒ
}

์ž…์ถœ๋ ฅ ์ตœ์ ํ™”

// ๋น ๋ฅธ ์ž…๋ ฅ
inline int fastInput() {
    int x = 0;
    char c = getchar();
    bool neg = false;
    
    while (c < '0' || c > '9') {
        if (c == '-') neg = true;
        c = getchar();
    }
    
    while (c >= '0' && c <= '9') {
        x = x * 10 + (c - '0');
        c = getchar();
    }
    
    return neg ? -x : x;
}

// ๋ฒ„ํผ๋ง๋œ ์ถœ๋ ฅ
class FastOutput {
    static const int BUFFER_SIZE = 1 << 16;
    char buffer[BUFFER_SIZE];
    int pos = 0;
    
public:
    ~FastOutput() { flush(); }
    
    void flush() {
        fwrite(buffer, 1, pos, stdout);
        pos = 0;
    }
    
    void print(int x) {
        if (x < 0) {
            buffer[pos++] = '-';
            x = -x;
        }
        
        char digits[20];
        int len = 0;
        do {
            digits[len++] = '0' + x % 10;
            x /= 10;
        } while (x);
        
        while (len--) {
            buffer[pos++] = digits[len];
        }
        buffer[pos++] = '\n';
        
        if (pos > BUFFER_SIZE - 100) flush();
    }
};

์ปดํŒŒ์ผ ํƒ€์ž„ ์ตœ์ ํ™”

// ํ…œํ”Œ๋ฆฟ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ
template<int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static constexpr int value = 1;
};

// ์‚ฌ์šฉ
constexpr int fact5 = Factorial<5>::value;  // 120

// SFINAE๋ฅผ ์ด์šฉํ•œ ํƒ€์ž… ์ฒดํฌ
template<typename T>
using EnableIfIntegral = enable_if_t<is_integral_v<T>, bool>;

template<typename T, EnableIfIntegral<T> = true>
T safe_add(T a, T b) {
    if (a > 0 && b > numeric_limits<T>::max() - a) {
        throw overflow_error("Integer overflow");
    }
    return a + b;
}

๐Ÿ“ 2๋‹จ๊ณ„ ํ•ต์‹ฌ ์š”์•ฝ

Python/Java ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฃผ์˜ํ•  ์ 

  1. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ: ์ˆ˜๋™ ๊ด€๋ฆฌ, RAII ํŒจํ„ด ํ™œ์šฉ
  2. ํฌ์ธํ„ฐ์™€ ์ฐธ์กฐ: ๋ช…ํ™•ํ•œ ๊ตฌ๋ถ„๊ณผ ํ™œ์šฉ
  3. ํ…œํ”Œ๋ฆฟ: ์ปดํŒŒ์ผ ํƒ€์ž„ ๋‹คํ˜•์„ฑ
  4. ์ด๋™ ์˜๋ฏธ๋ก : ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ํ•ต์‹ฌ

C++๋‹ค์šด ์ฝ”๋”ฉ ์Šคํƒ€์ผ

  1. RAII ํ™œ์šฉ: ์ž์› ๊ด€๋ฆฌ ์ž๋™ํ™”
  2. STL ์•Œ๊ณ ๋ฆฌ์ฆ˜: ๋ฐ˜๋ณต๋ฌธ ๋Œ€์‹  ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ
  3. const ์ •ํ™•์„ฑ: const๋ฅผ ์ ๊ทน ํ™œ์šฉ
  4. ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ: raw ํฌ์ธํ„ฐ ๋Œ€์‹  ์‚ฌ์šฉ

์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ios_base::sync_with_stdio(false)๋กœ ์ž…์ถœ๋ ฅ ์ตœ์ ํ™”
  • ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ for๋ฌธ๊ณผ auto ํ™œ์šฉ
  • STL ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋žŒ๋‹ค ์กฐํ•ฉ
  • ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
  • constexpr๋กœ ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ณ„์‚ฐ
  • ์ด๋™ ์˜๋ฏธ๋ก ์œผ๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™”
  • ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ œ๋„ค๋ฆญ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

C++ PS 3๋‹จ๊ณ„: PS ํ•ต์‹ฌ ํŒจํ„ด

๐Ÿ” 1. ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (DFS/BFS ํ…œํ”Œ๋ฆฟ)

DFS (๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰)

์žฌ๊ท€์  DFS

vector<vector<int>> graph;
vector<bool> visited;

void dfs_recursive(int node) {
    visited[node] = true;
    cout << node << ' ';  // ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
    
    for (int neighbor : graph[node]) {
        if (!visited[neighbor]) {
            dfs_recursive(neighbor);
        }
    }
}

// ์‚ฌ์šฉ ์˜ˆ์‹œ
int main() {
    int n = 6;  // ๋…ธ๋“œ ์ˆ˜
    graph.resize(n);
    visited.resize(n, false);
    
    // ๊ทธ๋ž˜ํ”„ ๊ตฌ์„ฑ
    graph[0] = {1, 2};
    graph[1] = {0, 3, 4};
    graph[2] = {0, 5};
    graph[3] = {1};
    graph[4] = {1, 5};
    graph[5] = {2, 4};
    
    dfs_recursive(0);
}

์Šคํƒ์„ ์ด์šฉํ•œ DFS

void dfs_iterative(int start) {
    vector<bool> visited(graph.size(), false);
    stack<int> st;
    st.push(start);
    
    while (!st.empty()) {
        int node = st.top();
        st.pop();
        
        if (!visited[node]) {
            visited[node] = true;
            cout << node << ' ';  // ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
            
            // ์—ญ์ˆœ์œผ๋กœ ์ถ”๊ฐ€ (์žฌ๊ท€์™€ ๊ฐ™์€ ์ˆœ์„œ)
            for (int i = graph[node].size() - 1; i >= 0; i--) {
                if (!visited[graph[node][i]]) {
                    st.push(graph[node][i]);
                }
            }
        }
    }
}

2์ฐจ์› ๊ฒฉ์ž์—์„œ DFS

int dx[] = {-1, 1, 0, 0};  // ์ƒํ•˜์ขŒ์šฐ
int dy[] = {0, 0, -1, 1};

void dfs_grid(vector<vector<int>>& grid, int x, int y, 
              vector<vector<bool>>& visited) {
    int n = grid.size();
    int m = grid[0].size();
    
    // ๊ฒฝ๊ณ„ ์ฒดํฌ ๋ฐ ๋ฐฉ๋ฌธ ์ฒดํฌ
    if (x < 0 || x >= n || y < 0 || y >= m || 
        visited[x][y] || grid[x][y] == 0) {
        return;
    }
    
    visited[x][y] = true;
    cout << "๋ฐฉ๋ฌธ: (" << x << ", " << y << ")\n";
    
    // 4๋ฐฉํ–ฅ ํƒ์ƒ‰
    for (int i = 0; i < 4; i++) {
        dfs_grid(grid, x + dx[i], y + dy[i], visited);
    }
}

// ์—ฐ๊ฒฐ ์š”์†Œ ๊ฐœ์ˆ˜ ๊ตฌํ•˜๊ธฐ
int countComponents(vector<vector<int>>& grid) {
    int n = grid.size();
    int m = grid[0].size();
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    int count = 0;
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1 && !visited[i][j]) {
                dfs_grid(grid, i, j, visited);
                count++;
            }
        }
    }
    
    return count;
}

BFS (๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰)

๊ธฐ๋ณธ BFS

void bfs(int start) {
    vector<bool> visited(graph.size(), false);
    queue<int> q;
    
    visited[start] = true;
    q.push(start);
    
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        cout << node << ' ';  // ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
        
        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}

์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” BFS

int bfs_shortest_path(int start, int end) {
    vector<int> distance(graph.size(), -1);
    queue<int> q;
    
    distance[start] = 0;
    q.push(start);
    
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        
        if (node == end) {
            return distance[end];
        }
        
        for (int neighbor : graph[node]) {
            if (distance[neighbor] == -1) {
                distance[neighbor] = distance[node] + 1;
                q.push(neighbor);
            }
        }
    }
    
    return -1;  // ๊ฒฝ๋กœ๊ฐ€ ์—†์Œ
}

2์ฐจ์› ๊ฒฉ์ž์—์„œ BFS

int bfs_grid(vector<vector<int>>& grid, int startX, int startY) {
    int n = grid.size();
    int m = grid[0].size();
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    queue<pair<pair<int, int>, int>> q;  // {{x, y}, dist}
    
    visited[startX][startY] = true;
    q.push({{startX, startY}, 0});
    
    while (!q.empty()) {
        auto [pos, dist] = q.front();
        auto [x, y] = pos;
        q.pop();
        
        cout << "๋ฐฉ๋ฌธ: (" << x << ", " << y << "), ๊ฑฐ๋ฆฌ: " << dist << '\n';
        
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            
            if (nx >= 0 && nx < n && ny >= 0 && ny < m &&
                !visited[nx][ny] && grid[nx][ny] == 1) {
                
                visited[nx][ny] = true;
                q.push({{nx, ny}, dist + 1});
            }
        }
    }
    
    return -1;
}

๐Ÿšจ DFS/BFS ์ฃผ์š” ํ•จ์ •

  • ์žฌ๊ท€ DFS์˜ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ (๊ธฐ๋ณธ ์Šคํƒ ํฌ๊ธฐ ์ œํ•œ)
  • BFS์—์„œ ๋ฐฉ๋ฌธ ์ฒดํฌ๋ฅผ ํ์— ๋„ฃ์„ ๋•Œ ํ•ด์•ผ ์ค‘๋ณต ๋ฐฉ์ง€
  • 2์ฐจ์› ๋ฐฐ์—ด์—์„œ dx, dy ๋ฐฐ์—ด ์ˆœ์„œ ์‹ค์ˆ˜
  • ๊ทธ๋ž˜ํ”„ ํ‘œํ˜„ ๋ฐฉ์‹ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ vs ์ธ์ ‘ ํ–‰๋ ฌ)

๐Ÿ“Š 2. ์ •๋ ฌ๊ณผ ์ด์ง„ํƒ์ƒ‰ ํŒจํ„ด

๋‹ค์–‘ํ•œ ์ •๋ ฌ ๊ธฐ๋ฒ•

๊ธฐ๋ณธ ์ •๋ ฌ

// ๋ฒกํ„ฐ ์ •๋ ฌ
vector<int> arr = {3, 1, 4, 1, 5, 9, 2, 6};
sort(arr.begin(), arr.end());              // ์˜ค๋ฆ„์ฐจ์ˆœ
sort(arr.begin(), arr.end(), greater<int>());  // ๋‚ด๋ฆผ์ฐจ์ˆœ

// ๋ฐฐ์—ด ์ •๋ ฌ
int arr2[] = {3, 1, 4, 1, 5};
sort(arr2, arr2 + 5);

์ปค์Šคํ…€ ์ •๋ ฌ

// ๊ตฌ์กฐ์ฒด ์ •๋ ฌ
struct Student {
    string name;
    int score;
    int age;
};

vector<Student> students = {
    {"Alice", 85, 20}, 
    {"Bob", 90, 19}, 
    {"Charlie", 85, 21}
};

// ์ ์ˆ˜ ๋‚ด๋ฆผ์ฐจ์ˆœ, ๊ฐ™์œผ๋ฉด ๋‚˜์ด ์˜ค๋ฆ„์ฐจ์ˆœ
sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
    if (a.score != b.score) return a.score > b.score;
    return a.age < b.age;
});

// pair ์ •๋ ฌ (์ž๋™์œผ๋กœ first, second ์ˆœ)
vector<pair<int, int>> pairs = {{3, 1}, {1, 4}, {1, 2}};
sort(pairs.begin(), pairs.end());

์•ˆ์ • ์ •๋ ฌ

// stable_sort๋Š” ๊ฐ™์€ ๊ฐ’์˜ ์›๋ž˜ ์ˆœ์„œ ์œ ์ง€
vector<pair<string, int>> data = {
    {"A", 1}, {"B", 2}, {"C", 1}, {"D", 2}
};
stable_sort(data.begin(), data.end(), [](const auto& a, const auto& b) {
    return a.second < b.second;
});
// ๊ฒฐ๊ณผ: {{"A", 1}, {"C", 1}, {"B", 2}, {"D", 2}}

๊ธฐ๋ณธ ์ด์ง„ํƒ์ƒ‰

int binary_search_manual(vector<int>& arr, int target) {
    int left = 0, right = arr.size() - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;  // ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€
        
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    
    return -1;  // ์ฐพ์ง€ ๋ชปํ•จ
}

// STL ์ด์ง„ํƒ์ƒ‰
vector<int> arr = {1, 3, 5, 7, 9};
if (binary_search(arr.begin(), arr.end(), 5)) {
    cout << "Found\n";
}

Lower Bound / Upper Bound

// ์ง์ ‘ ๊ตฌํ˜„
int lower_bound_manual(vector<int>& arr, int target) {
    int left = 0, right = arr.size();
    
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    
    return left;
}

// STL ํ™œ์šฉ
vector<int> arr = {1, 2, 2, 2, 3, 4, 5};
auto lower = lower_bound(arr.begin(), arr.end(), 2);
auto upper = upper_bound(arr.begin(), arr.end(), 2);
int count = upper - lower;  // 2์˜ ๊ฐœ์ˆ˜: 3

// ์ธ๋ฑ์Šค๋กœ ๋ณ€ํ™˜
int lower_idx = lower - arr.begin();
int upper_idx = upper - arr.begin();
// ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ตœ์†Ÿ๊ฐ’/์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ
bool check(int mid, /* ํ•„์š”ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ */) {
    // mid๊ฐ€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธ
    return true;  // or false
}

int parametric_search(int left, int right) {
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (check(mid)) {
            result = mid;  // ๊ฐ€๋Šฅํ•œ ๊ฐ’ ์ €์žฅ
            right = mid - 1;  // ๋” ์ž‘์€ ๊ฐ’ ํƒ์ƒ‰ (์ตœ์†Ÿ๊ฐ’)
            // left = mid + 1;  // ๋” ํฐ ๊ฐ’ ํƒ์ƒ‰ (์ตœ๋Œ“๊ฐ’)
        } else {
            left = mid + 1;  // ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ๋” ํฐ ๊ฐ’
            // right = mid - 1;  // ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ๋” ์ž‘์€ ๊ฐ’
        }
    }
    
    return result;
}

// ์˜ˆ์‹œ: ๋‚˜๋ฌด ์ž๋ฅด๊ธฐ
bool can_cut_wood(vector<int>& trees, int height, int target) {
    long long total = 0;
    for (int tree : trees) {
        if (tree > height) {
            total += tree - height;
        }
    }
    return total >= target;
}

int find_max_height(vector<int>& trees, int target) {
    int left = 0, right = *max_element(trees.begin(), trees.end());
    int result = 0;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (can_cut_wood(trees, mid, target)) {
            result = mid;
            left = mid + 1;  // ๋” ๋†’์€ ๋†’์ด ์‹œ๋„
        } else {
            right = mid - 1;
        }
    }
    
    return result;
}

๐Ÿšจ ์ •๋ ฌ/์ด์ง„ํƒ์ƒ‰ ์ฃผ์š” ํ•จ์ •

  • ์ด์ง„ํƒ์ƒ‰ ์ „ ์ •๋ ฌ ํ•„์ˆ˜
  • mid = (left + right) / 2๋Š” ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์œ„ํ—˜
  • lower_bound๋Š” ์ด์ƒ, upper_bound๋Š” ์ดˆ๊ณผ
  • ์‹ค์ˆ˜ํ˜• ์ด์ง„ํƒ์ƒ‰์€ ํšŸ์ˆ˜๋กœ ์ œํ•œ

๐Ÿ‘ฅ 3. ํˆฌ ํฌ์ธํ„ฐ, ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ

ํˆฌ ํฌ์ธํ„ฐ ๊ธฐ๋ฒ•

๊ธฐ๋ณธ ํˆฌ ํฌ์ธํ„ฐ

// ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ํ•ฉ์ด target์ธ ๋‘ ์ˆ˜ ์ฐพ๊ธฐ
pair<int, int> two_sum_sorted(vector<int>& arr, int target) {
    int left = 0, right = arr.size() - 1;
    
    while (left < right) {
        int sum = arr[left] + arr[right];
        
        if (sum == target) {
            return {left, right};
        } else if (sum < target) {
            left++;
        } else {
            right--;
        }
    }
    
    return {-1, -1};
}

์—ฐ์† ๋ถ€๋ถ„๋ฐฐ์—ด์˜ ํ•ฉ

// ํ•ฉ์ด target์ธ ์—ฐ์† ๋ถ€๋ถ„๋ฐฐ์—ด์˜ ๊ฐœ์ˆ˜
int subarray_sum(vector<int>& arr, int target) {
    int left = 0;
    long long sum = 0;
    int count = 0;
    
    for (int right = 0; right < arr.size(); right++) {
        sum += arr[right];
        
        while (sum > target && left <= right) {
            sum -= arr[left];
            left++;
        }
        
        if (sum == target) {
            count++;
        }
    }
    
    return count;
}

// ํ•ฉ์ด target ์ด์ƒ์ธ ์ตœ์†Œ ๊ธธ์ด ๋ถ€๋ถ„๋ฐฐ์—ด
int min_subarray_length(vector<int>& arr, int target) {
    int left = 0;
    long long sum = 0;
    int min_len = INT_MAX;
    
    for (int right = 0; right < arr.size(); right++) {
        sum += arr[right];
        
        while (sum >= target) {
            min_len = min(min_len, right - left + 1);
            sum -= arr[left];
            left++;
        }
    }
    
    return (min_len == INT_MAX) ? 0 : min_len;
}

์„œ๋กœ ๋‹ค๋ฅธ ๋ฌธ์ž์˜ ์ตœ์žฅ ๋ถ€๋ถ„๋ฌธ์ž์—ด

int longest_unique_substring(string s) {
    unordered_set<char> char_set;
    int left = 0;
    int max_length = 0;
    
    for (int right = 0; right < s.length(); right++) {
        while (char_set.count(s[right])) {
            char_set.erase(s[left]);
            left++;
        }
        
        char_set.insert(s[right]);
        max_length = max(max_length, right - left + 1);
    }
    
    return max_length;
}

// K๊ฐœ ์ดํ•˜์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋Š” ์ตœ์žฅ ๋ถ€๋ถ„๋ฌธ์ž์—ด
int longest_k_distinct(string s, int k) {
    unordered_map<char, int> char_count;
    int left = 0;
    int max_length = 0;
    
    for (int right = 0; right < s.length(); right++) {
        char_count[s[right]]++;
        
        while (char_count.size() > k) {
            char_count[s[left]]--;
            if (char_count[s[left]] == 0) {
                char_count.erase(s[left]);
            }
            left++;
        }
        
        max_length = max(max_length, right - left + 1);
    }
    
    return max_length;
}

์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ

๊ณ ์ • ํฌ๊ธฐ ์œˆ๋„์šฐ

// ํฌ๊ธฐ๊ฐ€ k์ธ ๋ถ€๋ถ„๋ฐฐ์—ด์˜ ์ตœ๋Œ€ ํ•ฉ
int max_sum_subarray(vector<int>& arr, int k) {
    if (arr.size() < k) return -1;
    
    // ์ฒซ ๋ฒˆ์งธ ์œˆ๋„์šฐ
    int window_sum = 0;
    for (int i = 0; i < k; i++) {
        window_sum += arr[i];
    }
    int max_sum = window_sum;
    
    // ์œˆ๋„์šฐ ์Šฌ๋ผ์ด๋”ฉ
    for (int i = k; i < arr.size(); i++) {
        window_sum = window_sum - arr[i - k] + arr[i];
        max_sum = max(max_sum, window_sum);
    }
    
    return max_sum;
}

// ํฌ๊ธฐ๊ฐ€ k์ธ ์œˆ๋„์šฐ์˜ ์ตœ๋Œ“๊ฐ’๋“ค
vector<int> sliding_window_maximum(vector<int>& arr, int k) {
    deque<int> dq;  // ์ธ๋ฑ์Šค ์ €์žฅ
    vector<int> result;
    
    for (int i = 0; i < arr.size(); i++) {
        // ์œˆ๋„์šฐ ๋ฒ”์œ„ ๋ฒ—์–ด๋‚œ ์›์†Œ ์ œ๊ฑฐ
        while (!dq.empty() && dq.front() < i - k + 1) {
            dq.pop_front();
        }
        
        // ํ˜„์žฌ ์›์†Œ๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋“ค ์ œ๊ฑฐ
        while (!dq.empty() && arr[dq.back()] < arr[i]) {
            dq.pop_back();
        }
        
        dq.push_back(i);
        
        if (i >= k - 1) {
            result.push_back(arr[dq.front()]);
        }
    }
    
    return result;
}

๋ฌธ์ž์—ด ํŒจํ„ด ๋งค์นญ

// ๋ฌธ์ž์—ด s์—์„œ p์˜ ์• ๋„ˆ๊ทธ๋žจ์ธ ๋ถ€๋ถ„๋ฌธ์ž์—ด ์ฐพ๊ธฐ
vector<int> find_anagrams(string s, string p) {
    vector<int> result;
    if (p.length() > s.length()) return result;
    
    vector<int> p_count(26, 0), window_count(26, 0);
    
    // p์˜ ๋ฌธ์ž ๋นˆ๋„ ๊ณ„์‚ฐ
    for (char c : p) {
        p_count[c - 'a']++;
    }
    
    // ์ฒซ ๋ฒˆ์งธ ์œˆ๋„์šฐ
    for (int i = 0; i < p.length(); i++) {
        window_count[s[i] - 'a']++;
    }
    
    if (window_count == p_count) {
        result.push_back(0);
    }
    
    // ์œˆ๋„์šฐ ์Šฌ๋ผ์ด๋”ฉ
    for (int i = p.length(); i < s.length(); i++) {
        window_count[s[i] - 'a']++;
        window_count[s[i - p.length()] - 'a']--;
        
        if (window_count == p_count) {
            result.push_back(i - p.length() + 1);
        }
    }
    
    return result;
}

๐Ÿšจ ํˆฌ ํฌ์ธํ„ฐ/์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ์ฃผ์š” ํ•จ์ •

  • ํฌ์ธํ„ฐ ์ด๋™ ์กฐ๊ฑด ๋ช…ํ™•ํžˆ ์ •์˜
  • ์œˆ๋„์šฐ ํฌ๊ธฐ์™€ ๊ฒฝ๊ณ„ ์กฐ๊ฑด ์ฃผ์˜
  • ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๊ฐ€๋Šฅ์„ฑ ์ฒดํฌ
  • deque ํ™œ์šฉํ•œ ์ตœ๋Œ“๊ฐ’/์ตœ์†Ÿ๊ฐ’ ์ถ”์ 

๐Ÿƒ 4. ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŒจํ„ด

๊ธฐ๋ณธ ๊ทธ๋ฆฌ๋”” ํŒจํ„ด

ํ™œ๋™ ์„ ํƒ ๋ฌธ์ œ

// ๋๋‚˜๋Š” ์‹œ๊ฐ„์ด ๋น ๋ฅธ ์ˆœ์œผ๋กœ ์ตœ๋Œ€ํ•œ ๋งŽ์€ ํ™œ๋™ ์„ ํƒ
int activity_selection(vector<pair<int, int>>& activities) {
    // ๋๋‚˜๋Š” ์‹œ๊ฐ„ ๊ธฐ์ค€ ์ •๋ ฌ
    sort(activities.begin(), activities.end(), 
         [](const auto& a, const auto& b) {
             return a.second < b.second;
         });
    
    int count = 1;
    int last_end = activities[0].second;
    
    for (int i = 1; i < activities.size(); i++) {
        if (activities[i].first >= last_end) {
            count++;
            last_end = activities[i].second;
        }
    }
    
    return count;
}

๊ฑฐ์Šค๋ฆ„๋ˆ ๋ฌธ์ œ

// ๊ฐ€์žฅ ์ ์€ ๊ฐœ์ˆ˜์˜ ๋™์ „์œผ๋กœ ๊ฑฐ์Šค๋ฆ„๋ˆ ๋งŒ๋“ค๊ธฐ
vector<int> make_change(int amount, vector<int>& coins) {
    sort(coins.begin(), coins.end(), greater<int>());
    vector<int> result;
    
    for (int coin : coins) {
        while (amount >= coin) {
            result.push_back(coin);
            amount -= coin;
        }
    }
    
    return (amount == 0) ? result : vector<int>();
}

์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ (ํฌ๋ฃจ์Šค์นผ)

struct Edge {
    int u, v, weight;
    bool operator<(const Edge& other) const {
        return weight < other.weight;
    }
};

class UnionFind {
    vector<int> parent, rank;
public:
    UnionFind(int n) : parent(n), rank(n, 0) {
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }
    
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    bool unite(int x, int y) {
        int px = find(x);
        int py = find(y);
        
        if (px == py) return false;
        
        if (rank[px] < rank[py]) {
            parent[px] = py;
        } else if (rank[px] > rank[py]) {
            parent[py] = px;
        } else {
            parent[py] = px;
            rank[px]++;
        }
        
        return true;
    }
};

int kruskal(int n, vector<Edge>& edges) {
    sort(edges.begin(), edges.end());
    UnionFind uf(n);
    int total_weight = 0;
    int edge_count = 0;
    
    for (const Edge& e : edges) {
        if (uf.unite(e.u, e.v)) {
            total_weight += e.weight;
            edge_count++;
            if (edge_count == n - 1) break;
        }
    }
    
    return total_weight;
}

๊ทธ๋ฆฌ๋”” ์„ ํƒ์˜ ์ •๋‹น์„ฑ

ํšŒ์˜์‹ค ๋ฐฐ์ •

// ์ตœ์†Œํ•œ์˜ ํšŒ์˜์‹ค๋กœ ๋ชจ๋“  ํšŒ์˜ ๋ฐฐ์ •
int meeting_rooms(vector<pair<int, int>>& meetings) {
    vector<int> starts, ends;
    
    for (const auto& meeting : meetings) {
        starts.push_back(meeting.first);
        ends.push_back(meeting.second);
    }
    
    sort(starts.begin(), starts.end());
    sort(ends.begin(), ends.end());
    
    int rooms = 0, max_rooms = 0;
    int i = 0, j = 0;
    
    while (i < starts.size()) {
        if (starts[i] < ends[j]) {
            rooms++;
            max_rooms = max(max_rooms, rooms);
            i++;
        } else {
            rooms--;
            j++;
        }
    }
    
    return max_rooms;
}

// Priority Queue ํ™œ์šฉ
int meeting_rooms_pq(vector<pair<int, int>>& meetings) {
    if (meetings.empty()) return 0;
    
    sort(meetings.begin(), meetings.end());
    priority_queue<int, vector<int>, greater<int>> pq;
    
    pq.push(meetings[0].second);
    
    for (int i = 1; i < meetings.size(); i++) {
        if (meetings[i].first >= pq.top()) {
            pq.pop();
        }
        pq.push(meetings[i].second);
    }
    
    return pq.size();
}

๐Ÿšจ ๊ทธ๋ฆฌ๋”” ์ฃผ์š” ํ•จ์ •

  • ๊ทธ๋ฆฌ๋”” ์„ ํƒ์ด ํ•ญ์ƒ ์ตœ์ ํ•ด ๋ณด์žฅํ•˜์ง€ ์•Š์Œ
  • ์ •๋ ฌ ๊ธฐ์ค€ ์„ ํƒ์ด ์ค‘์š”
  • ๋ฐ˜๋ก€ ์ฐพ๊ธฐ๋กœ ๊ฒ€์ฆ ํ•„์š”
  • ๋™์ ๊ณ„ํš๋ฒ•๊ณผ ๊ตฌ๋ถ„

๐Ÿงฎ 5. ๋™์ ๊ณ„ํš๋ฒ•(DP) ๊ธฐ๋ณธ ํŒจํ„ด

๊ธฐ๋ณธ DP ํŒจํ„ด

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด

// Top-down (๋ฉ”๋ชจ์ด์ œ์ด์…˜)
vector<long long> memo;

long long fibonacci_memo(int n) {
    if (n <= 1) return n;
    
    if (memo[n] != -1) return memo[n];
    
    return memo[n] = fibonacci_memo(n-1) + fibonacci_memo(n-2);
}

// Bottom-up
long long fibonacci_dp(int n) {
    if (n <= 1) return n;
    
    vector<long long> dp(n + 1);
    dp[0] = 0;
    dp[1] = 1;
    
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    
    return dp[n];
}

// ๊ณต๊ฐ„ ์ตœ์ ํ™”
long long fibonacci_optimized(int n) {
    if (n <= 1) return n;
    
    long long prev2 = 0, prev1 = 1;
    
    for (int i = 2; i <= n; i++) {
        long long current = prev1 + prev2;
        prev2 = prev1;
        prev1 = current;
    }
    
    return prev1;
}

0-1 ๋ฐฐ๋‚ญ ๋ฌธ์ œ

// ๊ธฐ๋ณธ 2์ฐจ์› DP
int knapsack_01(vector<int>& weights, vector<int>& values, int capacity) {
    int n = weights.size();
    vector<vector<int>> dp(n + 1, vector<int>(capacity + 1, 0));
    
    for (int i = 1; i <= n; i++) {
        for (int w = 1; w <= capacity; w++) {
            // i๋ฒˆ์งธ ๋ฌผ๊ฑด์„ ๋„ฃ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
            dp[i][w] = dp[i-1][w];
            
            // i๋ฒˆ์งธ ๋ฌผ๊ฑด์„ ๋„ฃ๋Š” ๊ฒฝ์šฐ
            if (weights[i-1] <= w) {
                dp[i][w] = max(dp[i][w], 
                              dp[i-1][w-weights[i-1]] + values[i-1]);
            }
        }
    }
    
    return dp[n][capacity];
}

// ๊ณต๊ฐ„ ์ตœ์ ํ™” (1์ฐจ์› DP)
int knapsack_01_optimized(vector<int>& weights, vector<int>& values, int capacity) {
    vector<int> dp(capacity + 1, 0);
    
    for (int i = 0; i < weights.size(); i++) {
        // ๋’ค์—์„œ๋ถ€ํ„ฐ ๊ฐฑ์‹  (์ค‘๋ณต ์‚ฌ์šฉ ๋ฐฉ์ง€)
        for (int w = capacity; w >= weights[i]; w--) {
            dp[w] = max(dp[w], dp[w - weights[i]] + values[i]);
        }
    }
    
    return dp[capacity];
}

์ตœ์žฅ ์ฆ๊ฐ€ ๋ถ€๋ถ„ ์ˆ˜์—ด (LIS)

// O(nยฒ) DP
int lis_dp(vector<int>& arr) {
    int n = arr.size();
    vector<int> dp(n, 1);
    
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (arr[j] < arr[i]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    
    return *max_element(dp.begin(), dp.end());
}

// O(n log n) ์ด์ง„ํƒ์ƒ‰
int lis_binary_search(vector<int>& arr) {
    vector<int> tails;
    
    for (int num : arr) {
        auto it = lower_bound(tails.begin(), tails.end(), num);
        if (it == tails.end()) {
            tails.push_back(num);
        } else {
            *it = num;
        }
    }
    
    return tails.size();
}

// LIS ๋ณต์›
vector<int> lis_with_path(vector<int>& arr) {
    int n = arr.size();
    vector<int> dp(n, 1);
    vector<int> parent(n, -1);
    
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (arr[j] < arr[i] && dp[j] + 1 > dp[i]) {
                dp[i] = dp[j] + 1;
                parent[i] = j;
            }
        }
    }
    
    // ์ตœ๋Œ€ ๊ธธ์ด์™€ ๋ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ
    int max_length = 0, end_idx = -1;
    for (int i = 0; i < n; i++) {
        if (dp[i] > max_length) {
            max_length = dp[i];
            end_idx = i;
        }
    }
    
    // ๊ฒฝ๋กœ ๋ณต์›
    vector<int> lis;
    for (int i = end_idx; i != -1; i = parent[i]) {
        lis.push_back(arr[i]);
    }
    reverse(lis.begin(), lis.end());
    
    return lis;
}

ํŽธ์ง‘ ๊ฑฐ๋ฆฌ (Edit Distance)

int edit_distance(string s1, string s2) {
    int m = s1.length(), n = s2.length();
    vector<vector<int>> dp(m + 1, vector<int>(n + 1));
    
    // ์ดˆ๊ธฐํ™”
    for (int i = 0; i <= m; i++) dp[i][0] = i;
    for (int j = 0; j <= n; j++) dp[0][j] = j;
    
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1[i-1] == s2[j-1]) {
                dp[i][j] = dp[i-1][j-1];
            } else {
                dp[i][j] = 1 + min({
                    dp[i-1][j],    // ์‚ญ์ œ
                    dp[i][j-1],    // ์‚ฝ์ž…
                    dp[i-1][j-1]   // ๊ต์ฒด
                });
            }
        }
    }
    
    return dp[m][n];
}

DP ์ƒํƒœ ์„ค๊ณ„ ํŒจํ„ด

๊ตฌ๊ฐ„ DP

// ํ–‰๋ ฌ ์—ฐ์‡„ ๊ณฑ์…ˆ
int matrix_chain_multiplication(vector<pair<int, int>>& matrices) {
    int n = matrices.size();
    vector<vector<int>> dp(n, vector<int>(n, 0));
    
    // ๊ตฌ๊ฐ„ ๊ธธ์ด๋ฅผ ๋Š˜๋ ค๊ฐ€๋ฉฐ ๊ณ„์‚ฐ
    for (int len = 2; len <= n; len++) {
        for (int i = 0; i <= n - len; i++) {
            int j = i + len - 1;
            dp[i][j] = INT_MAX;
            
            for (int k = i; k < j; k++) {
                int cost = dp[i][k] + dp[k+1][j] + 
                          matrices[i].first * matrices[k].second * matrices[j].second;
                dp[i][j] = min(dp[i][j], cost);
            }
        }
    }
    
    return dp[0][n-1];
}

๋น„ํŠธ๋งˆ์Šคํฌ DP

// ์™ธํŒ์› ๋ฌธ์ œ (TSP)
int tsp(vector<vector<int>>& dist) {
    int n = dist.size();
    vector<vector<int>> dp(1 << n, vector<int>(n, INT_MAX));
    
    // ์‹œ์ž‘์ ์—์„œ ์ถœ๋ฐœ
    dp[1][0] = 0;
    
    for (int mask = 1; mask < (1 << n); mask++) {
        for (int i = 0; i < n; i++) {
            if (!(mask & (1 << i))) continue;
            
            for (int j = 0; j < n; j++) {
                if (i == j || !(mask & (1 << j))) continue;
                
                int prev_mask = mask ^ (1 << i);
                if (dp[prev_mask][j] != INT_MAX) {
                    dp[mask][i] = min(dp[mask][i], 
                                     dp[prev_mask][j] + dist[j][i]);
                }
            }
        }
    }
    
    // ๋ชจ๋“  ๋„์‹œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ์‹œ์ž‘์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ์ตœ์†Œ ๋น„์šฉ
    int result = INT_MAX;
    int final_mask = (1 << n) - 1;
    for (int i = 1; i < n; i++) {
        if (dp[final_mask][i] != INT_MAX) {
            result = min(result, dp[final_mask][i] + dist[i][0]);
        }
    }
    
    return result;
}

๐Ÿšจ DP ์ฃผ์š” ํ•จ์ •

  • ์ƒํƒœ ์ •์˜๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”
  • ์ดˆ๊ธฐ๊ฐ’ ์„ค์ • ์ฃผ์˜
  • ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ ๊ณ ๋ ค (์ƒํƒœ ์••์ถ•)
  • Top-down vs Bottom-up ์„ ํƒ

๐Ÿ”ค 6. ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•

ํŒจํ„ด ๋งค์นญ

KMP ์•Œ๊ณ ๋ฆฌ์ฆ˜

// ์‹คํŒจ ํ•จ์ˆ˜ ๊ตฌ์ถ•
vector<int> build_failure_function(string pattern) {
    int m = pattern.length();
    vector<int> failure(m, 0);
    int j = 0;
    
    for (int i = 1; i < m; i++) {
        while (j > 0 && pattern[i] != pattern[j]) {
            j = failure[j - 1];
        }
        
        if (pattern[i] == pattern[j]) {
            j++;
            failure[i] = j;
        }
    }
    
    return failure;
}

// KMP ๊ฒ€์ƒ‰
vector<int> kmp_search(string text, string pattern) {
    int n = text.length(), m = pattern.length();
    vector<int> matches;
    
    if (m == 0) return matches;
    
    vector<int> failure = build_failure_function(pattern);
    int j = 0;
    
    for (int i = 0; i < n; i++) {
        while (j > 0 && text[i] != pattern[j]) {
            j = failure[j - 1];
        }
        
        if (text[i] == pattern[j]) {
            j++;
        }
        
        if (j == m) {
            matches.push_back(i - m + 1);
            j = failure[j - 1];
        }
    }
    
    return matches;
}

๋ผ๋นˆ-์นดํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜

vector<int> rabin_karp_search(string text, string pattern) {
    const int base = 256;
    const int mod = 1e9 + 7;
    int n = text.length(), m = pattern.length();
    vector<int> matches;
    
    if (m > n) return matches;
    
    // ํŒจํ„ด์˜ ํ•ด์‹œ๊ฐ’
    long long pattern_hash = 0;
    for (char c : pattern) {
        pattern_hash = (pattern_hash * base + c) % mod;
    }
    
    // base^(m-1) % mod
    long long h = 1;
    for (int i = 0; i < m - 1; i++) {
        h = (h * base) % mod;
    }
    
    // ์ฒซ ์œˆ๋„์šฐ์˜ ํ•ด์‹œ๊ฐ’
    long long window_hash = 0;
    for (int i = 0; i < m; i++) {
        window_hash = (window_hash * base + text[i]) % mod;
    }
    
    // ๋กค๋ง ํ•ด์‹œ
    for (int i = 0; i <= n - m; i++) {
        if (window_hash == pattern_hash) {
            if (text.substr(i, m) == pattern) {
                matches.push_back(i);
            }
        }
        
        if (i < n - m) {
            window_hash = (window_hash - text[i] * h % mod + mod) % mod;
            window_hash = (window_hash * base + text[i + m]) % mod;
        }
    }
    
    return matches;
}

๋ฌธ์ž์—ด ๋ณ€ํ™˜๊ณผ ์ฒ˜๋ฆฌ

ํšŒ๋ฌธ ๊ฒ€์‚ฌ์™€ ๊ด€๋ จ ์•Œ๊ณ ๋ฆฌ์ฆ˜

// ๊ธฐ๋ณธ ํšŒ๋ฌธ ๊ฒ€์‚ฌ
bool is_palindrome(string s) {
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s[left] != s[right]) return false;
        left++;
        right--;
    }
    return true;
}

// ์ค‘์‹ฌ ํ™•์žฅ์œผ๋กœ ์ตœ์žฅ ํšŒ๋ฌธ
string longest_palindrome_expand(string s) {
    auto expand_around_center = [&](int left, int right) {
        while (left >= 0 && right < s.length() && s[left] == s[right]) {
            left--;
            right++;
        }
        return right - left - 1;
    };
    
    int start = 0, max_len = 0;
    for (int i = 0; i < s.length(); i++) {
        int len1 = expand_around_center(i, i);      // ํ™€์ˆ˜ ๊ธธ์ด
        int len2 = expand_around_center(i, i + 1);  // ์ง์ˆ˜ ๊ธธ์ด
        
        int len = max(len1, len2);
        if (len > max_len) {
            max_len = len;
            start = i - (len - 1) / 2;
        }
    }
    
    return s.substr(start, max_len);
}

// Manacher's Algorithm (O(n))
string manacher_algorithm(string s) {
    // ์ „์ฒ˜๋ฆฌ: ๋ฌธ์ž ์‚ฌ์ด์— ํŠน์ˆ˜ ๋ฌธ์ž ์‚ฝ์ž…
    string processed = "#";
    for (char c : s) {
        processed += c;
        processed += '#';
    }
    
    int n = processed.length();
    vector<int> radius(n, 0);
    int center = 0, right = 0;
    
    for (int i = 0; i < n; i++) {
        if (i < right) {
            radius[i] = min(right - i, radius[2 * center - i]);
        }
        
        // ์ค‘์‹ฌ ํ™•์žฅ
        while (i - radius[i] - 1 >= 0 && 
               i + radius[i] + 1 < n &&
               processed[i - radius[i] - 1] == processed[i + radius[i] + 1]) {
            radius[i]++;
        }
        
        // ์˜ค๋ฅธ์ชฝ ๊ฒฝ๊ณ„ ๊ฐฑ์‹ 
        if (i + radius[i] > right) {
            center = i;
            right = i + radius[i];
        }
    }
    
    // ์ตœ์žฅ ํšŒ๋ฌธ ์ฐพ๊ธฐ
    int max_len = 0, center_idx = 0;
    for (int i = 0; i < n; i++) {
        if (radius[i] > max_len) {
            max_len = radius[i];
            center_idx = i;
        }
    }
    
    int start = (center_idx - max_len) / 2;
    return s.substr(start, max_len);
}

์ ‘๋ฏธ์‚ฌ ๋ฐฐ์—ด

// ๋‹จ์ˆœ ๊ตฌํ˜„ O(nยฒlog n)
vector<int> suffix_array_naive(string s) {
    int n = s.length();
    vector<pair<string, int>> suffixes;
    
    for (int i = 0; i < n; i++) {
        suffixes.push_back({s.substr(i), i});
    }
    
    sort(suffixes.begin(), suffixes.end());
    
    vector<int> sa;
    for (const auto& suffix : suffixes) {
        sa.push_back(suffix.second);
    }
    
    return sa;
}

// LCP ๋ฐฐ์—ด
vector<int> lcp_array(string s, vector<int>& sa) {
    int n = s.length();
    vector<int> rank(n), lcp(n - 1);
    
    for (int i = 0; i < n; i++) {
        rank[sa[i]] = i;
    }
    
    int h = 0;
    for (int i = 0; i < n; i++) {
        if (rank[i] > 0) {
            int j = sa[rank[i] - 1];
            while (i + h < n && j + h < n && s[i + h] == s[j + h]) {
                h++;
            }
            lcp[rank[i] - 1] = h;
            if (h > 0) h--;
        }
    }
    
    return lcp;
}

ํŠธ๋ผ์ด (Trie)

class TrieNode {
public:
    TrieNode* children[26];
    bool is_end;
    
    TrieNode() {
        is_end = false;
        for (int i = 0; i < 26; i++) {
            children[i] = nullptr;
        }
    }
};

class Trie {
private:
    TrieNode* root;
    
public:
    Trie() {
        root = new TrieNode();
    }
    
    void insert(string word) {
        TrieNode* node = root;
        for (char c : word) {
            int idx = c - 'a';
            if (!node->children[idx]) {
                node->children[idx] = new TrieNode();
            }
            node = node->children[idx];
        }
        node->is_end = true;
    }
    
    bool search(string word) {
        TrieNode* node = root;
        for (char c : word) {
            int idx = c - 'a';
            if (!node->children[idx]) {
                return false;
            }
            node = node->children[idx];
        }
        return node->is_end;
    }
    
    bool starts_with(string prefix) {
        TrieNode* node = root;
        for (char c : prefix) {
            int idx = c - 'a';
            if (!node->children[idx]) {
                return false;
            }
            node = node->children[idx];
        }
        return true;
    }
};

๐Ÿšจ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ ์ฃผ์š” ํ•จ์ •

  • ๋ฌธ์ž์—ด ์ธ๋ฑ์Šค ๋ฒ”์œ„ ์ฒดํฌ
  • ์œ ๋‹ˆ์ฝ”๋“œ ์ฒ˜๋ฆฌ ์ฃผ์˜
  • ํ•ด์‹œ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ (ํŠนํžˆ Trie)

๐Ÿš€ PS ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•๊ณผ ์ตœ์ ํ™”

์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”์™€ Pragma

์ปดํŒŒ์ผ ์˜ต์…˜

# GCC/Clang ์ตœ์ ํ™” ์˜ต์…˜
g++ -O2 -std=c++17 solution.cpp -o solution

# ์ถ”๊ฐ€ ์œ ์šฉํ•œ ์˜ต์…˜๋“ค
g++ -O2 -std=c++17 -Wall -Wextra -Wshadow \
    -DLOCAL -DDEBUG solution.cpp -o solution

# ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”
g++ -O2 -std=c++17 -ffast-math -march=native solution.cpp

# ๋””๋ฒ„๊น…์šฉ
g++ -g -std=c++17 -fsanitize=address -fsanitize=undefined solution.cpp

Pragma ์ง€์‹œ๋ฌธ

// ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")

// ๊ฒฝ๊ณ  ๋ฌด์‹œ
#pragma GCC diagnostic ignored "-Wunused-variable"

// ๊ตฌ์กฐ์ฒด ํŒจํ‚น
#pragma pack(push, 1)
struct PackedStruct {
    char c;
    int i;
};
#pragma pack(pop)

// ๋ฉ”๋ชจ๋ฆฌ ์ •๋ ฌ
struct alignas(64) AlignedStruct {
    int data[16];
};

// ํ•จ์ˆ˜ ์ธ๋ผ์ธ ๊ฐ•์ œ
inline __attribute__((always_inline)) int fastAdd(int a, int b) {
    return a + b;
}

์ž…์ถœ๋ ฅ ์ตœ์ ํ™” ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•

// ๊ทนํ•œ ์ตœ์ ํ™” ์ž…์ถœ๋ ฅ
namespace FastIO {
    const int BUFFER_SIZE = 1 << 20;
    char input_buffer[BUFFER_SIZE];
    char output_buffer[BUFFER_SIZE];
    char *input_ptr = input_buffer;
    char *output_ptr = output_buffer;
    
    void init() {
        fread(input_buffer, 1, BUFFER_SIZE, stdin);
    }
    
    void flush() {
        fwrite(output_buffer, 1, output_ptr - output_buffer, stdout);
        output_ptr = output_buffer;
    }
    
    int read_int() {
        int result = 0;
        bool negative = false;
        
        while (*input_ptr < '0' || *input_ptr > '9') {
            if (*input_ptr == '-') negative = true;
            input_ptr++;
        }
        
        while (*input_ptr >= '0' && *input_ptr <= '9') {
            result = result * 10 + (*input_ptr - '0');
            input_ptr++;
        }
        
        return negative ? -result : result;
    }
    
    void write_int(int x) {
        if (x < 0) {
            *output_ptr++ = '-';
            x = -x;
        }
        
        char digits[20];
        int len = 0;
        do {
            digits[len++] = '0' + x % 10;
            x /= 10;
        } while (x);
        
        while (len--) {
            *output_ptr++ = digits[len];
        }
        *output_ptr++ = '\n';
    }
}

๋ฉ”๋ชจ๋ฆฌ ๋ฐ ์„ฑ๋Šฅ ์ตœ์ ํ™”

// ์Šคํƒ ํฌ๊ธฐ ๋Š˜๋ฆฌ๊ธฐ (์žฌ๊ท€ ๊นŠ์ด ์ฆ๊ฐ€)
#pragma GCC optimize("O3")
#pragma GCC target("avx2")

int main() {
    // ์Šคํƒ ํฌ๊ธฐ ์„ค์ • (Linux/Mac)
    const rlim_t stack_size = 256 * 1024 * 1024; // 256MB
    struct rlimit rl;
    getrlimit(RLIMIT_STACK, &rl);
    rl.rlim_cur = stack_size;
    setrlimit(RLIMIT_STACK, &rl);
    
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    return 0;
}

// ๋ฉ”๋ชจ๋ฆฌ ํ’€ ์‚ฌ์šฉ
template<typename T, size_t POOL_SIZE = 1000000>
class MemoryPool {
    T pool[POOL_SIZE];
    size_t next_free = 0;
public:
    T* allocate() {
        return &pool[next_free++];
    }
    void reset() {
        next_free = 0;
    }
};

// ๋น„ํŠธ ์ตœ์ ํ™”
struct BitVector {
    vector<uint64_t> bits;
    size_t n;
    
    BitVector(size_t size) : n(size) {
        bits.resize((size + 63) / 64);
    }
    
    void set(size_t pos) {
        bits[pos / 64] |= (1ULL << (pos % 64));
    }
    
    bool get(size_t pos) const {
        return bits[pos / 64] & (1ULL << (pos % 64));
    }
};

PS ์ „์šฉ ๋งคํฌ๋กœ์™€ ํ…œํ”Œ๋ฆฟ

// ๊ณ ๊ธ‰ ๋งคํฌ๋กœ
#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define PRECISION(x) cout << fixed << setprecision(x)
#define FILE_IO freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

// ๋””๋ฒ„๊น… ๋งคํฌ๋กœ (๊ณ ๊ธ‰)
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

void debug_out() { cerr << endl; }
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}

// ๋ชจ๋“ˆ๋Ÿฌ ์—ฐ์‚ฐ ํด๋ž˜์Šค
template<int MOD>
struct ModInt {
    int val;
    ModInt(long long v = 0) { val = (-MOD <= v && v < MOD) ? v : v % MOD; if (val < 0) val += MOD; }
    ModInt& operator+=(const ModInt& other) { val += other.val; if (val >= MOD) val -= MOD; return *this; }
    ModInt& operator-=(const ModInt& other) { val -= other.val; if (val < 0) val += MOD; return *this; }
    ModInt& operator*=(const ModInt& other) { val = (1LL * val * other.val) % MOD; return *this; }
    ModInt operator+(const ModInt& other) const { return ModInt(*this) += other; }
    ModInt operator-(const ModInt& other) const { return ModInt(*this) -= other; }
    ModInt operator*(const ModInt& other) const { return ModInt(*this) *= other; }
};

using mint = ModInt<1000000007>;

// ์™„์ „ PS ํ…œํ”Œ๋ฆฟ
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("O3")
#pragma GCC target("avx2")

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

const int INF = 1e9;
const ll LLINF = 1e18;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
#define fi first
#define se second

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

void debug_out() { cerr << endl; }
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...); }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    // Solution here
    
    return 0;
}

์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ˆ˜ํ•™/๊ธฐํ•˜ ํ•จ์ˆ˜

// ์ˆ˜ํ•™ ์œ ํ‹ธ๋ฆฌํ‹ฐ
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll power(ll base, ll exp, ll mod) {
    ll result = 1;
    while (exp > 0) {
        if (exp & 1) result = (result * base) % mod;
        base = (base * base) % mod;
        exp >>= 1;
    }
    return result;
}

// ์†Œ์ˆ˜ ํŒ์ •
bool is_prime(ll n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    for (ll i = 3; i * i <= n; i += 2) {
        if (n % i == 0) return false;
    }
    return true;
}

// ์—๋ผํ† ์Šคํ…Œ๋„ค์Šค์˜ ์ฒด
vector<bool> sieve(int n) {
    vector<bool> prime(n + 1, true);
    prime[0] = prime[1] = false;
    for (int i = 2; i * i <= n; i++) {
        if (prime[i]) {
            for (int j = i * i; j <= n; j += i) {
                prime[j] = false;
            }
        }
    }
    return prime;
}

// ๊ธฐํ•˜ํ•™์  ์œ ํ‹ธ๋ฆฌํ‹ฐ
struct Point {
    ll x, y;
    Point(ll x = 0, ll y = 0) : x(x), y(y) {}
    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
    ll dot(const Point& p) const { return x * p.x + y * p.y; }
    ll cross(const Point& p) const { return x * p.y - y * p.x; }
    ll dist2() const { return x * x + y * y; }
};

๐Ÿ“ 3๋‹จ๊ณ„ ํ•ต์‹ฌ ์š”์•ฝ

ํ•„์ˆ˜ ์•”๊ธฐ ํ…œํ”Œ๋ฆฟ

  1. DFS/BFS: ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰์˜ ๊ธฐ๋ณธ
  2. ์ด์ง„ํƒ์ƒ‰: lower_bound, upper_bound, ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ์ƒ‰
  3. ํˆฌ ํฌ์ธํ„ฐ: ์—ฐ์† ๋ถ€๋ถ„๋ฐฐ์—ด, ๋‘ ์ˆ˜์˜ ํ•ฉ
  4. ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ: ๊ณ ์ •/๊ฐ€๋ณ€ ํฌ๊ธฐ ์œˆ๋„์šฐ
  5. ๊ทธ๋ฆฌ๋””: ์ •๋ ฌ ํ›„ ์„ ํƒ, ์ฆ๋ช… ํ•„์š”
  6. DP: ์ƒํƒœ ์ •์˜๊ฐ€ ํ•ต์‹ฌ, ์ ํ™”์‹ ๋„์ถœ

์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ ๊ฐ€์ด๋“œ

  • ์™„์ „ํƒ์ƒ‰ ๊ฐ€๋Šฅ? โ†’ DFS/BFS
  • ์ •๋ ฌ๋œ ๋ฐ์ดํ„ฐ? โ†’ ์ด์ง„ํƒ์ƒ‰
  • ์—ฐ์†๋œ ๊ตฌ๊ฐ„? โ†’ ํˆฌ ํฌ์ธํ„ฐ/์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ
  • ์ตœ์  ๋ถ€๋ถ„๊ตฌ์กฐ? โ†’ DP
  • ํƒ์š•์  ์„ ํƒ? โ†’ ๊ทธ๋ฆฌ๋””
  • ๋ฌธ์ž์—ด ํŒจํ„ด? โ†’ KMP/๋ผ๋นˆ-์นดํ”„/Trie

์‹œ๊ฐ„๋ณต์žก๋„ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • O(2^n): ๋ถ€๋ถ„์ง‘ํ•ฉ, ์™„์ „ํƒ์ƒ‰
  • O(n!): ์ˆœ์—ด
  • O(nยณ): 3์ค‘ ๋ฐ˜๋ณต๋ฌธ, ํ”Œ๋กœ์ด๋“œ
  • O(nยฒ): 2์ค‘ ๋ฐ˜๋ณต๋ฌธ, ๋‹จ์ˆœ DP
  • O(n log n): ์ •๋ ฌ, ์ด์ง„ํƒ์ƒ‰ ๊ธฐ๋ฐ˜
  • O(n): ์„ ํ˜• ํƒ์ƒ‰, ํˆฌ ํฌ์ธํ„ฐ
  • O(log n): ์ด์ง„ํƒ์ƒ‰
  • O(1): ํ•ด์‹œ ํ…Œ์ด๋ธ” ์ ‘๊ทผ

PS ์ตœ์ ํ™” ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • #pragma GCC optimize("O3") ์ถ”๊ฐ€
  • ios_base::sync_with_stdio(false) ์„ค์ •
  • ์ ์ ˆํ•œ ์ž๋ฃŒํ˜• ์„ ํƒ (int vs long long)
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๊ณ ๋ ค (vector vs array)
  • ์ƒ์ˆ˜ ์ตœ์ ํ™” (๋น„ํŠธ ์—ฐ์‚ฐ, ๋ชจ๋“ˆ๋Ÿฌ ์—ฐ์‚ฐ)
  • ์ž…์ถœ๋ ฅ ์ตœ์ ํ™” (scanf/printf vs cin/cout)
  • ์ปดํŒŒ์ผ๋Ÿฌ๋ณ„ ๋‚ด์žฅ ํ•จ์ˆ˜ ํ™œ์šฉ (__builtin_*)
  • ์บ์‹œ ์นœํ™”์  ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ ํŒจํ„ด