안녕하세요! 테크지니어22입니다.
오늘은 백준 알고리즘 2617번 - 구슬 찾기 를 풀어보도록 하겠습니다.
[문제 접근]
문제에서 답에 포함되는 상황은 특정 구슬이 (n+1)/ 2개보다 더 무겁거나 같은 구슬의 개수를 가지거나, 더 가볍거나 같은 구슬의 개수를 가지는 상황입니다. 그래서 저는 특정구슬보다 무거운 구슬들을 담는 공간과 특정구슬보다 가벼운 구슬 공간을 담기 위해 인접리스트 두 개를 이용했습니다. 특정 구슬의 인접리스트 원소 그리고 인접리스트 원소가 연결된 모든 원소들이 몇개인지 파악하기 위해 BFS를 생각했습니다.
[풀이 전략]
1. 인접리스트를 이용하여 구슬 간의 관계를 저장합니다.
2. 모든 구슬을 for문을 이용하여 방문합니다.
- for문의 한 턴이 시작될 때마다 방문 구슬을 저장하는 배열을 초기화합니다.
- BFS를 이용하기 위해 queue와 방문배열을 이용합니다.
- cnt 변수를 생성하여 구슬과 연결된(직접 혹은 간접) 구슬의 개수를 셉니다.
- cnt >= (n+1)/2 이면 정답에 포함시킵니다.
[코드]
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int m , n;
vector<int> adj1[100];
vector<int> adj2[100];
int vis[100];
queue<int> q ;
int result ;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m ;
while(m--) {
int a, b ;
cin >> a >> b ;
adj1[a].push_back(b);
adj2[b].push_back(a);
}
for(int i = 1 ; i <=n ; i++){
fill(vis,vis+100,0);
q.push(i);
vis[i] = 1 ;
int cnt = 0 ;
while (!q.empty())
{
auto cur = q.front() ; q.pop();
for(auto nxt : adj1[cur]){
if(vis[nxt]) continue;
q.push(nxt);
vis[nxt] = 1;
cnt++;
}
}
if(cnt >= (n+1)/2) {result++; continue;}
}
for(int i = 1 ; i <=n ; i++){
fill(vis,vis+100,0);
q.push(i);
vis[i] = 1 ;
int cnt = 0 ;
while (!q.empty())
{
auto cur = q.front() ; q.pop();
for(auto nxt : adj2[cur]){
if(vis[nxt]) continue;
q.push(nxt);
vis[nxt] = 1;
cnt++;
}
}
if(cnt >= (n+1)/2) result++;
}
cout << result ;
}
[배울 점]
- 공간복잡도도 고려해야 합니다.
- 반복성이 보이면 함수를 만드는 것이 효율적입니다.
- 방문여부 등의 저장배열의 초기화 타이밍을 신경써주어야 합니다.
- BFS의 기본 뼈대를 상기시켜야 합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준/C++] 알고리즘 1003번 - 피보나치 함수 (0) | 2024.04.11 |
---|---|
[백준/C++] 알고리즘 3190번 - 뱀 (0) | 2024.04.11 |
[백준/C++] 알고리즘 20922번 - 겹치는 건 싫어 (1) | 2024.04.09 |
[백준/C++] 알고리즘 2531번 - 회전 초밥 (0) | 2024.04.09 |
[백준/C++] 알고리즘 1405번 - 로봇 청소기 (0) | 2024.04.08 |