#include "1260.h"
// bfs에서 큐에 넣을 때 방문처리해야 중복 처리 안됨
// dfs에서 스택에 넣을 때 낮은 것부터 처리하려면 큰 것부터 넣어야 함
// vector를 인자로 넣으면 값 복사가 이루어져서 엄청난 오버헤드 발생
// 인자에 넣을 거면 포인터를 전달했어야 했음
namespace {
std::vector<std::vector<int>> graph;
std::vector<bool> dfs_visited;
void dfs(int node)
{
dfs_visited[node] = true;
std::cout << node << ' ';
for (int next_node : graph[node])
{
if (!dfs_visited[next_node])
dfs(next_node);
}
}
void bfs(int v)
{
std::queue<int> q;
std::vector<bool> visited(graph.size(), false);
q.push(v);
visited[v] = true;
while (!q.empty())
{
int node = q.front();
q.pop();
std::cout << node << ' ';
for (int next_node : graph[node])
{
if (!visited[next_node])
{
visited[next_node] = true;
q.push(next_node);
}
}
}
}
}
void B1260::Solution()
{
//int n, m, v;
//scanf("%d %d %d", &n, &m, &v);
//std::unordered_map<int, std::set<int>> g;
//std::vector<bool> visited(n+1, false);
//for (int i = 0; i < m; i++)
//{
// int a, b;
// scanf("%d %d", &a, &b);
// g[a].insert(b);
// g[b].insert(a);
//}
//// dfs
//std::stack<int> s;
//s.push(v);
//while (!s.empty())
//{
// int node = s.top();
// s.pop();
// if (visited[node]) continue;
// visited[node] = true;
// printf("%d ", node);
// for (auto it = g[node].rbegin(); it != g[node].rend(); ++it)
// {
// s.push(*it);
// }
//}
//printf("\n");
//std::fill(visited.begin(), visited.end(), false);
//// bfs
//std::queue<int> q;
//visited[v] = true;
//q.push(v);
//while (!q.empty())
//{
// int node = q.front();
// q.pop();
// printf("%d ", node);
// for (int i : g[node])
// {
// if (!visited[i]) {
// visited[i] = true;
// q.push(i);
// }
// }
//}
int n, m, v;
std::cin >> n >> m >> v;
graph.resize(n+1);
for (int i = 0; i < m; ++i)
{
int a, b;
std::cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
for (int i = 0; i < n + 1; ++i)
std::sort(graph[i].begin(), graph[i].end());
dfs_visited.resize(n + 1, false);
dfs(v);
std::cout << std::endl;
bfs(v);
}
map과 unordered_map 비교 (일종의 dict)
| 항목 | map | unordered_map |
|---|---|---|
| 내부 구조 | Red-Black Tree | Hash Table |
| 정렬 여부 | 자동 정렬 (key 순) | 없음 (순서 보장 안 됨) |
| 탐색/삽입 속도 | O(log n) | 평균 O(1), 최악 O(n) |
| 키 타입 조건 | < 비교 가능해야 함 | ==, hash 가능해야 함 |
익명 네임스페이스
// some.cpp
namespace {
void helper() {
std::cout << "파일 내부 전용\n";
}
}
void public_func() {
helper(); // ✅ 내부에서만 호출 가능
}
.cpp 파일 안에서만 사용되는 함수 선언 가능
cin, cout 화살표 구분
| 연산자 | 의미 | 방향 이미지 |
|---|---|---|
>> | 오른쪽 변수로 "넣는다" → | cin >> 변수 : 입력받아 변수에 넣음 |
<< | 오른쪽 값을 "보낸다" → | cout << 값 : 값을 출력 스트림에 보냄 |
cin, cout 속도 향상시키기
| 설정 | 효과 |
|---|---|
sync_with_stdio(false) | cin/cout 속도 크게 향상 |
cin.tie(0) | 자동 flush 비활성화 → 더 빠름 |
cout.tie(0) | 거의 영향 없음 (관성적으로 씀) |
namespace
{
int find_max_seq(int i, int j, std::vector<int>* fruits)
{
int max_count = 0;
// fruits를 순회하면서 i랑 j가 아니라면 카운트 초기화
int count = 0;
for (int f : *fruits)
{
if (f != i && f != j) { count = 0; }
else {
count++;
max_count = std::max(count, max_count);
}
}
return max_count;
}
}
void B30804::Solution()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector<int> fruits;
for (int i = 0; i < n; ++i)
{
int f;
std::cin >> f;
fruits.push_back(f);
}
// 그리디로 풀어도 O(n^2). 과일 개수 보니 불가능.
// 역으로 생각해서 두종류의 숫자로만 이루어진 연속된 수열 찾기
// 9C2 경우의 수만큼 두 종류만 골라서 연속된 수열 찾으면 O(kn)
int res = 0;
for (int i = 1; i <= 8; ++i)
{
for (int j = i+1; j <= 9; ++j)
{
res = std::max(res, find_max_seq(i, j, &fruits));
}
}
std::cout << res;
}
입력 바로 넣기
for (int i = 0; i < n; ++i)
{
int f;
std::cin >> f;
fruits.push_back(f);
}
이걸
for (int i = 0; i < n; ++i)
cin >> v[i];
이렇게 줄일 수 있다
#include <bits/stdc++.h>
using namespace std;
int N, types, cnt[10], answer;
queue<int> q;
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> N;
while (N--)
{
int fruit;
cin >> fruit;
q.push(fruit);
if (cnt[fruit]++ == 0)
{
++types;
}
while (types > 2)
{
fruit = q.front();
q.pop();
if (--cnt[fruit] == 0)
{
--types;
}
}
answer = max(answer, static_cast<int>(q.size()));
}
cout << answer;
}
굳이 다 받아놓고 슬라이딩 윈도우 안 해도, 넣으면서 슬라이딩 윈도우 할 수 있다.
간단한 n번 for문
while(n--)
{
}