Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- BOJ
- 3343
- 1174
- backtracking #codetree #디버깅 #삼성코테
- c++ #boj #
- 최소 #공배수 #최대 #공약수 #유클리드 #호제법 #lcm #gcd #c++ #boj #3343 #백준 #장미
- hcpc
- 백준 #다익스트라 #dijkstra #9370 #c++
- 투포인터 #백준 #boj #20922 #22862
- 코딩
- N번째큰수
- 이분탐색 #dp #11053
- 30870
- 3D #Reconstruction #computer #vision #volume #metric #tsdf #kinect #fusion
- boj #백준
- 줄어드는수
- 레드아보
- 백준
- 16202
- graph #최단경로
- 진법변환 #2to10 #10to2 #이진법 #십진법 #변환 #bitset #c++
- 사이클 없는 그래프
- 20117
- LIS #가장긴증가하는부분수열 #
- graph
- 쌤쌤쌤
- c++ #입출력 #속도 #ios #sync_with_stdio #cin #cout #tie
- C++
- 22869
- 호반우 상인
Archives
- Today
- Total
hyunjin
[BOJ 2933 미네랄] 구현 그래프 너비 깊이 우선 본문
728x90
문제 포인트는 제거 이후 움질일 클러스터를 찾는 부분
문제에서
공중에 떠 있는 미네랄 클러스터는 없으며, 두 개 또는 그 이상의 클러스터가 동시에 떨어지는 경우도 없다.
라는 조건이 주어졌다.
하지만 잘생각해보면 아래와 같은 케이스가 있다.
3 3
xxx
x.x
..x
1
3
.xx
..x
x.x
움직이는 클러스더가 (2,1) 하나이긴 하지만 (1,1)이 제거된 이후에 움직일 가능성이 있는 것은 (2,1)과 (1,2) 클러스터 2개이다. 물론 (1,2) 클러스터가 움직이지 않아서 결론적으로 하나의 클러스터만 움직이지만 그것을 확인하는 과정에선 여러 클러스터가 움직일 가능성이 있다고 판단.
처음엔 이걸 생각못하고 제거되는 위치의 아래는 확인하지 않았다.
#include <iostream>
#include <vector>
#include <cstring>
#include <tuple>
#define MAX_N 101
#define EMPTY '.'
#define MINERAL 'x'
using namespace std;
typedef pair<int, int> pii;
int H, W;
char grid[MAX_N][MAX_N];
bool vis[MAX_N][MAX_N];
vector<pii> vec;
int dy[4] = { 0,0,-1,1 };
int dx[4] = { -1,1,0,0 };
bool InRange(int y, int x) {
return 1 <= y && y <= H && 1 <= x && x <= W;
}
bool CanGo(int y, int x) {
return InRange(y, x) && grid[y][x] != EMPTY && !vis[y][x];
}
pii FindTarget(int h, bool left){
if (left) {
for (int i = 1; i <= W; i++)
if (grid[h][i] != EMPTY)
return { h,i };
}
else {
for (int i = W; i; i--)
if (grid[h][i] != EMPTY)
return{ h,i };
}
return { 0,0 };
}
void FindClustter(int y, int x) {
for (int d = 0; d < 4; d++) {
int ny = y + dy[d], nx = x + dx[d];
if (CanGo(ny,nx)){
vec.push_back({ ny,nx });
vis[ny][nx] = true;
FindClustter(ny, nx);
}
}
}
bool cmp(pii a, pii b) {
return a.first > b.first;
}
bool CanMove(int h) {
for (pii p : vec) {
if (h + p.first > H ||
grid[p.first + h][p.second] != EMPTY)
return false;
}
return true;
}
void Gravity() {
for (pii p : vec) {
grid[p.first][p.second] = EMPTY;
}
int h = 1;
while (1) {
if(!CanMove(h)) break;
h++;
}
h--;
for (pii p : vec) {
grid[p.first + h][p.second] = MINERAL;
}
}
void Simulate() {
int t;
cin >> t;
bool left = false;
while (t--) {
int h;
cin >> h;
h = H + 1 - h;
left ^= true;
int y, x;
tie(y,x) = FindTarget(h, left);
// 타켓 없으면 다음 턴 진행
if (make_pair(y,x) == make_pair(0, 0)) continue;
grid[y][x] = EMPTY;
memset(vis, 0, sizeof(vis));
vec.clear();
for (int d = 0; d < 4; d++) {
int ny = y + dy[d], nx = x + dx[d];
if (CanGo(ny, nx)) {
vec.push_back({ ny,nx });
vis[ny][nx] = true;
FindClustter(ny,nx);
Gravity();
vec.clear();
}
}
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> H >> W;
for (int i = 1; i <= H; i++) {
string s;
cin >> s;
for (int j = 1; j <= W; j++) {
grid[i][j] = s[j - 1];
}
}
Simulate();
for (int i = 1; i <= H; i++) {
for (int j = 1; j <= W; j++) {
cout << grid[i][j];
}
cout << "\n";
}
return 0;
}
728x90
'알고리즘 연습 > 백준' 카테고리의 다른 글
[BOJ 5875 오타 c++] 자료구조 누적 합 (0) | 2024.04.28 |
---|---|
[BOJ 3343 장미] 정수론, LCM (0) | 2024.04.25 |
[BOJ 9370 미확인 도착지] 다익스트라 dijkstra 그래프 최단경로 (0) | 2024.04.22 |
[투포인터 BOJ20922 BOJ22862] (0) | 2024.04.20 |
[가장 긴 증가하는 부분 수열] LIS, DP, 이분탐색 (0) | 2024.04.19 |