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๋จ๊ณ ํต์ฌ ์์ฝ#
๊ผญ ๊ธฐ์ตํด์ผ ํ ํจํด#
- ๋น ๋ฅธ ์
์ถ๋ ฅ:
ios_base::sync_with_stdio(false)์ '\n'
- ๋ฌธ์์ด ์ฒ๋ฆฌ:
substr(), find(), stringstream
- ๋ฒกํฐ ์กฐ์:
sort(), unique(), ๋ฒ์ ๊ธฐ๋ฐ for๋ฌธ
- ๋งต/์
:
find(), count(), unordered ๋ฒ์
- STL ์๊ณ ๋ฆฌ์ฆ:
accumulate(), transform(), copy_if()
- ๋๋ค ํํ์: ์ ๋ ฌ๊ณผ 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 ๊ฐ๋ฐ์๊ฐ ์ฃผ์ํ ์ #
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: ์๋ ๊ด๋ฆฌ, RAII ํจํด ํ์ฉ
- ํฌ์ธํฐ์ ์ฐธ์กฐ: ๋ช
ํํ ๊ตฌ๋ถ๊ณผ ํ์ฉ
- ํ
ํ๋ฆฟ: ์ปดํ์ผ ํ์ ๋คํ์ฑ
- ์ด๋ ์๋ฏธ๋ก : ์ฑ๋ฅ ์ต์ ํ์ ํต์ฌ
C++๋ค์ด ์ฝ๋ฉ ์คํ์ผ#
- RAII ํ์ฉ: ์์ ๊ด๋ฆฌ ์๋ํ
- STL ์๊ณ ๋ฆฌ์ฆ: ๋ฐ๋ณต๋ฌธ ๋์ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ
- const ์ ํ์ฑ: const๋ฅผ ์ ๊ทน ํ์ฉ
- ์ค๋งํธ ํฌ์ธํฐ: raw ํฌ์ธํฐ ๋์ ์ฌ์ฉ
์์ฃผ ์ฌ์ฉํ๋ ํจํด ์ฒดํฌ๋ฆฌ์คํธ#
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}}
์ด์งํ์ (Binary Search)#
๊ธฐ๋ณธ ์ด์งํ์#
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();
๋งค๊ฐ๋ณ์ ํ์ (Parametric Search)#
// ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ต์๊ฐ/์ต๋๊ฐ ์ฐพ๊ธฐ
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๋จ๊ณ ํต์ฌ ์์ฝ#
ํ์ ์๊ธฐ ํ
ํ๋ฆฟ#
- DFS/BFS: ๊ทธ๋ํ ํ์์ ๊ธฐ๋ณธ
- ์ด์งํ์: lower_bound, upper_bound, ๋งค๊ฐ๋ณ์ ํ์
- ํฌ ํฌ์ธํฐ: ์ฐ์ ๋ถ๋ถ๋ฐฐ์ด, ๋ ์์ ํฉ
- ์ฌ๋ผ์ด๋ฉ ์๋์ฐ: ๊ณ ์ /๊ฐ๋ณ ํฌ๊ธฐ ์๋์ฐ
- ๊ทธ๋ฆฌ๋: ์ ๋ ฌ ํ ์ ํ, ์ฆ๋ช
ํ์
- 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 ์ต์ ํ ์ฒดํฌ๋ฆฌ์คํธ#