Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DFS_BFS] 10월 10일 #10

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions 08_DFS_BFS/1325.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//DFS_BFS 필수 1번: 1325 효율적인 해킹
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

vector<vector<int>> adj;
vector<bool> visit;
vector<int> result;
int maxCount = -1;

void bfs(int start)
{
queue<int> q;
q.push(start);
visit[start] = true;
int count = 0;

while (!q.empty())
{
int node = q.front();
q.pop();

for (int next : adj[node])
{
if (!visit[next])
{
q.push(next);
visit[next] = true;
count++;
}
}
}

result[start] = count;
maxCount = max(maxCount, count);
}

int main()
{
int n, m;
cin >> n >> m;

adj.resize(n + 1);
visit.resize(n + 1, false);
result.resize(n + 1, 0);

for (int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
adj[b].push_back(a);
}

for (int i = 1; i <= n; i++)
{
fill(visit.begin(), visit.end(), false);
bfs(i);
}

for (int i = 1; i <= n; i++)
{
if (result[i] == maxCount) {
cout << i << " ";
}
}

return 0;
}
74 changes: 74 additions & 0 deletions 08_DFS_BFS/19538.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// DFS_BFS 도전 1번: 19538 루머
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

int n, m;
vector<vector<int>> graph;
queue<int> q;
vector<int> time;
vector<int> neighbor;

void bfs() {
while (!q.empty())
{
int nowNode = q.front();
q.pop();

for (int next : graph[nowNode])
{
// 이웃에게 난 루머를 알고있다고 전파
neighbor[next]++;

// 시간이 기록 돼 있지 않고 && 본인 노드 수 / 2 <= 본인 이웃 노드가 알고있는 루머 수
if (time[next] == -1 && (graph[next].size() + 1) / 2 <= neighbor[next])
{
q.push(next);
time[next] = time[nowNode] + 1;
}
}
}
}

int main()
{

cin >> n;
graph.resize(n + 1);
time.resize(n + 1, -1);
neighbor.resize(n + 1, 0);

for (int i = 1; i <= n; i++)
{
int a;
while (true)
{
cin >> a;
if (a == 0) break;
graph[i].push_back(a);
}
}

cin >> m;

for (int i = 0; i < m; i++)
{
int node;
cin >> node;
time[node] = 0;
q.push(node);
}

bfs();

for (int i = 1; i <= n; i++)
{
cout << time[i];
if (i != n) cout << " ";
}

return 0;
}
73 changes: 73 additions & 0 deletions 08_DFS_BFS/2615.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//DFS_BFS 필수 2번: 2615 오목
#include <iostream>
#include <vector>

using namespace std;

bool isInside(int x, int y)
{
return x >= 0 && x < 19 && y >= 0 && y < 19;
}
Comment on lines +7 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좌표의 유효성을 체크하는 부분을 따로 함수로 분리하셨네요! 코드가 깔끔하고 의미도 명확해보여서 좋은 것 같습니다 👍


int checkWin(const vector<vector<int>>& board, int x, int y) {
int dx[4] = {1, 0, 1, -1}; // 가로, 세로, 대각선 방향을 나타내는 x 좌표 변화값
int dy[4] = {0, 1, 1, 1}; // 가로, 세로, 대각선 방향을 나타내는 y 좌표 변화값

for (int dir = 0; dir < 4; ++dir)
{
int count = 1; // 연속된 바둑알의 개수 초기화
int nx = x + dx[dir]; // 다음 검사할 x 좌표 계산
int ny = y + dy[dir]; // 다음 검사할 y 좌표 계산

while (isInside(nx, ny) && board[nx][ny] == board[x][y])
{
count++; // 같은 색 바둑알 개수 증가
nx += dx[dir]; // 다음 검사할 x 좌표 갱신
ny += dy[dir]; // 다음 검사할 y 좌표 갱신
}

if (count == 5) { // 연속된 바둑알이 5개인 경우
// 승부가 결정된 경우
int prev_x = x - dx[dir];
int prev_y = y - dy[dir];
if (!isInside(prev_x, prev_y) || board[prev_x][prev_y] != board[x][y]) {
// 승리한 플레이어의 색과 다른 색이 놓인 경우에만 승부로 인정
return board[x][y];
}
}
}

return 0; // 승리 조건 미충족
}

int main()
{
vector<vector<int>> board(19, vector<int>(19, 0)); // 19x19 바둑판 초기화

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 바둑판의 크기(19)가 초기화할 때, for문을 돌 때 반복적으로 사용되는데 상수로 정의하면 어떤가요? 자주 사용되는 숫자 같은 경우에는 따로 상수로 정의해서 사용하는게 가독성도 좋고 실수의 위험도 줄여줄 수 있어요!


// 바둑판 상태 입력
for (int i = 0; i < 19; ++i)
{
for (int j = 0; j < 19; ++j) {
cin >> board[i][j]; // 각 위치의 바둑알 상태 입력
}
}

for (int i = 0; i < 19; ++i)
{
for (int j = 0; j < 19; ++j)
{
if (board[i][j] != 0)
{ // 빈 칸이 아닌 경우
int result = checkWin(board, i, j); // 승리 여부 확인
if (result != 0)
{ // 승부가 결정된 경우
cout << result << '\n' << i + 1 << ' ' << j + 1 << '\n'; // 승리한 플레이어와 위치 출력
return 0;
}
}
Comment on lines +59 to +67

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 인덴테이션은 가능하면 적게 유지하는게 좋아요! 중첩 if문 대신 continue를 사용해서 빈 칸인 경우 패스를 하고, 그 다음에 승리 여부를 확인하는 건 어떨까요??

}
}

cout << "0\n"; // 아직 승부가 결정되지 않은 경우
return 0;
}
92 changes: 92 additions & 0 deletions 08_DFS_BFS/4963.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//DFS_BFS 필수 3번: 4963 섬의 개수
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
const int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

bool isInside(int x, int y, int w, int h)
{
return (x >= 0 && x < w && y >= 0 && y < h);
}

void bfs(int x, int y, vector<vector<int>>& grid, vector<vector<bool>>& visited)
{
int w = grid.size();
int h = grid[0].size();

queue<pair<int, int>> q;
q.push(make_pair(x, y));
visited[x][y] = true;

while (!q.empty())
{
int curX = q.front().first;
int curY = q.front().second;
q.pop();

for (int i = 0; i < 8; ++i)
{
int newX = curX + dx[i];
int newY = curY + dy[i];

if (isInside(newX, newY, w, h) && grid[newX][newY] == 1 && !visited[newX][newY])
{
q.push(make_pair(newX, newY));
visited[newX][newY] = true;
}
}
}
}

int countIslands(vector<vector<int>>& grid)
{
int w = grid.size();
int h = grid[0].size();
vector<vector<bool>> visited(w, vector<bool>(h, false));
int islandCount = 0;

for (int i = 0; i < w; ++i)
{
for (int j = 0; j < h; ++j)
{
if (grid[i][j] == 1 && !visited[i][j])
{
bfs(i, j, grid, visited);
islandCount++;
}
}
}

return islandCount;
}

int main()
{
while (true)
{
int w, h;
cin >> w >> h;

if (w == 0 && h == 0) {
break;
}

vector<vector<int>> grid(w, vector<int>(h));
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
cin >> grid[j][i];
}
}

int islandCount = countIslands(grid);
cout << islandCount << "\n";
}

return 0;
}
53 changes: 53 additions & 0 deletions 08_DFS_BFS/게임_맵_최단거리.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//DFS_BFS 도전 2번: 게임_맵_최단거리
#include <vector>
#include <queue>
using namespace std;

int solution(vector<vector<int>> maps)
{
int n = maps.size();
int m = maps[0].size();

vector<vector<int>> dist(n, vector<int>(m, -1));
queue<pair<int, int>> q;

// 시작 위치와 도착 위치 초기화
q.push({0, 0});
dist[0][0] = 1;

// 상하좌우 이동 방향
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};

while (!q.empty())
{
int r = q.front().first;
int c = q.front().second;
q.pop();

// 상대 팀 진영에 도착하면 거리 반환
if (r == n - 1 && c == m - 1) {
return dist[r][c];
}

// 상하좌우 이동
for (int i = 0; i < 4; i++)
{
int nr = r + dr[i];
int nc = c + dc[i];

// 유효한 위치인지 확인
if (nr >= 0 && nr < n && nc >= 0 && nc < m)
{
// 벽이 아니고 아직 방문하지 않은 곳인 경우
if (maps[nr][nc] == 1 && dist[nr][nc] == -1) {
dist[nr][nc] = dist[r][c] + 1;
q.push({nr, nc});
}
}
}
}

// 상대 팀 진영에 도착할 수 없는 경우
return -1;
}