Backjoon Online Judge
"10216번 : Count Circle Groups" 문제입니다.
문제 링크 : https://www.acmicpc.net/problem/2667
문제 및 코드 설명입니다.
'10216번 : Count Circle Groups' 문제의 경우 모든 좌표쌍을 기준으로 그룹 여부를 판단해야 하는 문제로 조금 까다로울 수 있는 문제였습니다.
문제 풀이는 Union Find를 이용한다면 더 쉽고 빠르게 풀 수 있겠지만 DFS로 문제 분류가 되어있어 이번에는 DFS로 해결하였습니다.
(Union Find를 이용한 풀이도 추후 시도 할 예정입니다.)
먼저 적군의 진영을 저장하기 위한 벡터를 만들고 벡터에 4개의 정보(x,y,R,visit)를 저장하기 위해 pair를 이용하였습니다.
적군의 진영의 수는 N이므로 벡터의 첫번째부터 N번째까지 dfs 탐색을 진행했습니다.
이때 방문되지 않은 진영이라면 서로 다른 진영으로 분류하였고, 진영의 수(=group_num)을 더해주었습니다.
DFS는 위의 반복문에서 방문되지 않은 진영을 발견하였을 때 호출하였고, 그 진영으로부터 통신 가능한 진영을 모두 파악합니다.
DFS를 통해 현재 진영으로 부터 방문 될 수 있는 진영을 모두 파악하여 그 진영의 visit 값을 1로 설정합니다.
위 과정을 반복하여 N개의 진영을 모두 조사한다면 서로 다른 진영의 갯수를 출력하게 됩니다.
코드는 C++로 작성하였습니다.
- pair문을 사용하면 (구버전)C++ 컴파일러에서 오류가 발생합니다. C++ 11 이상 컴파일러로 실행시 정상적으로 동작합니다.
- 21번째 라인에서 i의 시작을 k+1로 설정하여 결과에 오류가 발생했습니다. 코드 작성 시 참고 하시면 좋을 듯 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <iostream> #include <vector> #define Max 5001 using namespace std; typedef pair<pair<int, int>, pair<int, int>> pair4; int N, group_num; //그룹 갯수 vector<pair4> enemy; //순서대로 x, y, R, visit여부를 저장 //두 지점이 통신 가능한지를 비교 (가능하면 1) int compare(int a, int b) { int r = enemy[a].second.first + enemy[b].second.first; int x = enemy[a].first.first - enemy[b].first.first; int y = enemy[a].first.second - enemy[b].first.second; return (((x * x) + (y * y)) <= (r * r)) ? true : false; } void dfs(int k) { //(mistake)양방향으로 확인하기! for (int i = 0; i < N; i++) { if (enemy[i].second.second) { continue; } //통신 가능 하다면 if (compare(i, k)) { enemy[i].second.second = 1; enemy[k].second.second = 1; dfs(i); } } } int main() { int T, x, y, R; cin >> T; while (T--) { cin >> N; for (int i = 0; i < N; i++) { cin >> x >> y >> R; enemy.push_back(make_pair(make_pair(x, y), make_pair(R, 0))); } group_num = 0; for (int i = 0; i < N; i++) { if (!enemy[i].second.second) { //방문하지 않았다면 enemy[i].second.second = 1; dfs(i); group_num++; } } cout << group_num << endl; enemy.clear(); } } |
'Programming 문제풀이 > Backjoon Online Judge' 카테고리의 다른 글
2667번 : 단지번호붙이기 (0) | 2018.05.29 |
---|---|
2606번 : 바이러스 (0) | 2018.05.28 |
2178번 : 미로탐색 (0) | 2018.05.17 |
7569번 : 토마토 (0) | 2018.05.17 |
7576번 : 토마토 (0) | 2018.05.16 |