Skip to content

Commit 67d0278

Browse files
authored
Merge pull request #43 from bsa0322/sua_dfs&bfs_assign
[DFS & BFS] 04월 15일 (선택.cpp)
2 parents 90b0ea7 + acdeb0c commit 67d0278

File tree

6 files changed

+436
-0
lines changed

6 files changed

+436
-0
lines changed
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
5+
using namespace std;
6+
typedef pair<int, int> ci;
7+
8+
void greenToRed(int n, vector<vector<char>> &board) {
9+
for (int i = 0; i < n; i++) {
10+
for (int j = 0; j < n; j++) {
11+
if (board[i][j] == 'G') {
12+
board[i][j] = 'R';
13+
}
14+
}
15+
}
16+
}
17+
18+
void bfs(int n, int r, int c, vector<vector<bool>> &visited, vector<vector<char>> &board) {
19+
//상, 하, 좌, 우
20+
int dr[4] = {-1, 1, 0, 0};
21+
int dc[4] = {0, 0, -1, 1};
22+
23+
queue<ci> q;
24+
25+
//큐 초기화
26+
q.push({r, c});
27+
visited[r][c] = true;
28+
while (!q.empty()) {
29+
int cr = q.front().first;
30+
int cc = q.front().second;
31+
q.pop();
32+
33+
for (int i = 0; i < 4; i++) {
34+
int nr = cr + dr[i];
35+
int nc = cc + dc[i];
36+
if (nr < 0 || nr >= n || nc < 0 || nc >= n || visited[nr][nc]) {
37+
continue;
38+
}
39+
if (board[nr][nc] != board[cr][cc]) {
40+
continue;
41+
}
42+
q.push({nr, nc});
43+
visited[nr][nc] = true;
44+
}
45+
}
46+
}
47+
48+
int countArea(int n, vector<vector<char>> &board) {
49+
vector<vector<bool>> visited(n, vector<bool>(n, false));
50+
int area = 0;
51+
52+
for (int i = 0; i < n; i++) {
53+
for (int j = 0; j < n; j++) {
54+
if (visited[i][j]) {
55+
continue;
56+
}
57+
bfs(n, i, j, visited, board);
58+
area++;
59+
}
60+
}
61+
return area;
62+
}
63+
64+
/**
65+
* [적록색약]
66+
*
67+
* 그림의 색을 기준으로 구역을 나누는 문제
68+
* 1. 적록색약이 아닌 사람 기준으로 구역을 나눈다.
69+
* 2. 그림의 초록을 모두 빨강으로 바꾼 후, 적록색약인 사람 기준으로 구역을 나눈다.
70+
*/
71+
72+
int main() {
73+
int n;
74+
string s;
75+
76+
//입력
77+
cin >> n;
78+
vector<vector<char>> board(n, vector<char>(n, ' '));
79+
for (int i = 0; i < n; i++) {
80+
cin >> s;
81+
for (int j = 0; j < n; j++) {
82+
board[i][j] = s[j];
83+
}
84+
}
85+
86+
//연산 & 출력
87+
cout << countArea(n, board) << ' ';
88+
greenToRed(n, board);
89+
cout << countArea(n, board);
90+
return 0;
91+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <iostream>
2+
#include <vector>
3+
4+
using namespace std;
5+
6+
vector<vector<int>> adj_list;
7+
vector<int> parent;
8+
9+
void dfs_recursion(int prev, int curr) {
10+
if (parent[curr]) {
11+
return;
12+
}
13+
parent[curr] = prev;
14+
for (int i = 0; i < adj_list[curr].size(); i++) {
15+
dfs_recursion(curr, adj_list[curr][i]);
16+
}
17+
}
18+
19+
/**
20+
* [트리의 부모 찾기]
21+
*
22+
* 1번 노드에서 출발해서 탐색
23+
* 루트 노드에서 출발 했기 때문에, 현재 노드의 부모는 이전 노드가 된다.
24+
*/
25+
26+
int main() {
27+
int n, a, b;
28+
29+
//입력
30+
cin >> n;
31+
adj_list.assign(n + 1, vector<int>(0));
32+
parent.assign(n + 1, 0);
33+
for (int i = 1; i < n; i++) {
34+
cin >> a >> b;
35+
adj_list[a].push_back(b);
36+
adj_list[b].push_back(a);
37+
}
38+
39+
//연산
40+
dfs_recursion(1, 1); //1번 노드는 루트노드이므로, 부모를 자기 자신으로 설정
41+
42+
//출력
43+
for (int i = 2; i <= n; i++) {
44+
cout << parent[i] << '\n';
45+
}
46+
return 0;
47+
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <iostream>
2+
#include <queue>
3+
4+
using namespace std;
5+
const int SIZE = 1e5;
6+
7+
int bfs(int n, int k) {
8+
vector<int> check(SIZE + 1, 0);
9+
queue<int> q; //큐에 좌표값 저장
10+
int ans = 0;
11+
12+
check[n] = 1; //시작 노드 방문체크 + 시간 초기화
13+
q.push(n);
14+
while (!q.empty()) {
15+
int x = q.front();
16+
q.pop();
17+
18+
if (x == k) {
19+
ans = check[x] - 1;
20+
break;
21+
}
22+
23+
vector<int> child = {x - 1, x + 1, x * 2}; //자식 노드
24+
for (int i = 0; i < 3; i++) {
25+
if (child[i] >= 0 && child[i] <= SIZE && !check[child[i]]) {
26+
check[child[i]] = check[x] + 1;
27+
q.push(child[i]);
28+
}
29+
}
30+
}
31+
return ans;
32+
}
33+
34+
/**
35+
* [숨바꼭질]
36+
*
37+
* x좌표 위에서 x-1, x+1, 2*x의 위치로 계속 이동하며 탐색
38+
* 가장 빠른 시간을 찾아야 하므로 주변 노드부터 탐색하는 풀이로 풀어서 k에 도달하면 바로 탐색 종료 (bfs)
39+
*/
40+
41+
int main() {
42+
int n, k;
43+
44+
//입력
45+
cin >> n >> k;
46+
47+
//연산 & 출력
48+
cout << bfs(n, k);
49+
return 0;
50+
}
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
5+
using namespace std;
6+
7+
vector<int> bfs(vector<vector<int>> &people, vector<int> &init, int n) {
8+
vector<int> rest(n + 1, 0); //각 사람이 루머를 믿기 위해 필요한 최소 주변인 수
9+
vector<int> ans(n + 1, -1); //몇 분 후에 믿는지
10+
queue<int> q;
11+
12+
//시작 정점 초기화
13+
for (int i = 0; i < init.size(); i++) {
14+
ans[init[i]] = 0;
15+
q.push(init[i]);
16+
}
17+
18+
//루머 믿어야 하는 주변인 수 초기화
19+
for (int i = 1; i <= n; i++) {
20+
rest[i] = (people[i].size() + 1) / 2;
21+
}
22+
23+
while (!q.empty()) {
24+
int curr = q.front(); //현재 사람
25+
int t = ans[curr]; //루머 믿은 시간
26+
q.pop();
27+
28+
for (int i = 0; i < people[curr].size(); i++) {
29+
int next = people[curr][i];
30+
if (ans[next] > -1) { //이미 루머를 믿는 다면
31+
continue;
32+
}
33+
rest[next]--;
34+
if (!rest[next]) { //주변인들 중 절반 이상이 루머를 믿으면
35+
ans[next] = t + 1;
36+
q.push(next);
37+
}
38+
}
39+
}
40+
return ans;
41+
}
42+
43+
/**
44+
* [루머]
45+
*
46+
* 주변인들이 얼마나 믿는지를 배열을 통해 관리해야 함
47+
* 방문 체크 배열을 루머를 믿는 시간을 저장하는 배열로 대체함
48+
* ans[i] = -1 일 경우, i는 루머를 믿지 않는다
49+
* ans[i] = t인 경우, i는 t분 부터 루머를 믿기 시작함
50+
* 각자가 루머를 믿기 위해 주변인의 절반 이상이 루머를 믿어야 하므로, 각 사람이 루머를 믿기까지 루머를 믿는 주변인 몇명이 남았는지를 리스트에 기록한다.
51+
* 남은 사람이 0인 순간, 해당 사람은 루머를 믿기 시작
52+
*/
53+
54+
int main() {
55+
int n, m, input;
56+
57+
//루머 퍼뜨리는 관계 입력
58+
cin >> n;
59+
vector<vector<int>> people(n + 1, vector<int>());
60+
for (int i = 1; i <= n; i++) {
61+
while (true) {
62+
cin >> input;
63+
if (!input) {
64+
break;
65+
}
66+
people[i].push_back(input);
67+
}
68+
}
69+
70+
//최초 유포자 입력
71+
cin >> m;
72+
vector<int> init(m, 0);
73+
for (int i = 0; i < m; i++) {
74+
cin >> init[i];
75+
}
76+
77+
//연산
78+
vector<int> ans = bfs(people, init, n);
79+
80+
//출력
81+
for (int i = 1; i <= n; i++) {
82+
cout << ans[i] << ' ';
83+
}
84+
return 0;
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <algorithm>
5+
6+
using namespace std;
7+
typedef pair<int, int> ci;
8+
9+
//단지 내 집 개수 탐색하는 bfs
10+
int bfs(int n, int r, int c, vector<vector<bool>> &board) {
11+
int dr[4] = {-1, 1, 0, 0};
12+
int dc[4] = {0, 0, -1, 1};
13+
14+
queue<ci> q;
15+
16+
//큐 초기화
17+
q.push({r, c});
18+
board[r][c] = false;
19+
int cnt = 1;
20+
while (!q.empty()) {
21+
int cr = q.front().first;
22+
int cc = q.front().second;
23+
q.pop();
24+
25+
for (int i = 0; i < 4; i++) {
26+
int nr = cr + dr[i];
27+
int nc = cc + dc[i];
28+
if (nr < 0 || nr >= n || nc < 0 || nc >= n || !board[nr][nc]) {
29+
continue;
30+
}
31+
q.push({nr, nc});
32+
board[nr][nc] = false;
33+
cnt++;
34+
}
35+
}
36+
return cnt;
37+
}
38+
39+
//단지 수와 단지 내 집 개수 구하는 함수
40+
vector<int> cntComplex(int n, vector<vector<bool>> &board) {
41+
vector<int> complex;
42+
for (int i = 0; i < n; i++) {
43+
for (int j = 0; j < n; j++) {
44+
if (board[i][j]) {
45+
int cnt = bfs(n, i, j, board);
46+
complex.push_back(cnt);
47+
}
48+
}
49+
}
50+
return complex;
51+
}
52+
53+
/**
54+
* [단지 번호 붙이기] - bfs
55+
*
56+
* 단순 탐색
57+
* (주의) 단지 내 집의 수를 "오름차순"으로 출력
58+
*
59+
* 이 풀이에서는 방문체크 배열을 따로 사용하지 않고, 처음 지도에 표기를 1 -> 0으로 바꾸어 중복으로 탐색하지 않도록 함
60+
*/
61+
62+
int main() {
63+
int n;
64+
string s;
65+
66+
//입력
67+
cin >> n;
68+
vector<vector<bool>> board(n, vector<bool>(n, false));
69+
for (int i = 0; i < n; i++) {
70+
cin >> s;
71+
for (int j = 0; j < n; j++) {
72+
board[i][j] = s[j] - '0';
73+
}
74+
}
75+
76+
//연산
77+
vector<int> ans = cntComplex(n, board);
78+
sort(ans.begin(), ans.end());
79+
80+
//출력
81+
cout << ans.size() << '\n';
82+
for (int i = 0; i < ans.size(); i++) {
83+
cout << ans[i] << '\n';
84+
}
85+
return 0;
86+
}

0 commit comments

Comments
 (0)