https://www.acmicpc.net/problem/13460

이 문제는 겁나 복잡해보였지만 막상 풀고나니 이해하기 쉬웠다

그냥 두가지 케이스 빨간공 파란공 각각 움직인다음 겹칠때 혹은 구멍에 들어갈때의 조건식만 추가해주면 되었다

#include<iostream>
#include<string>
#include<queue>
using namespace std;
int arr[10][10];
struct INFO {
	int Rx, Ry, Bx, By, count;
};
int n, m;
INFO start;
int dx[4] = { 1,-1,0,0 };
int dy[4] = { 0,0,-1,1 };
int visited[11][11][11][11] = { 0, };
int bfs() {
	queue<INFO> bfsQ;
	bfsQ.push(start);

	int ans = -1;
	visited[start.Rx][start.Ry][start.Bx][start.By] = 1;
	while (!bfsQ.empty()) {
		INFO cur = bfsQ.front();
		bfsQ.pop();
		if (cur.count > 10)break;

		if (arr[cur.Rx][cur.Ry] == 4 && arr[cur.Bx][cur.By] != 4) {
			ans = cur.count;
			break;
		}

		for(int i=0; i<4; i++){
			int nextRy = cur.Ry;
			int nextRx = cur.Rx;
			int nextBy = cur.By;
			int nextBx = cur.Bx;
			while (1) {
				if (arr[nextRx][nextRy] != 1 and arr[nextRx][nextRy] != 4) {
					nextRx += dx[i];
					nextRy += dy[i];
				}
				else {
					if (arr[nextRx][nextRy] == 1) {
						nextRx -= dx[i]; 
						nextRy -= dy[i]; //벽일 경우 이전위치로
					}
					break;
				}
			}

			//blue 구슬 벽이나 구멍일때까지 한 방향으로 이동함
			while (1) {
				if (arr[nextBx][nextBy] != 1 and arr[nextBx][nextBy] != 4) {
					nextBx += dx[i];
					nextBy += dy[i];
				}
				else {
					if (arr[nextBx][nextBy] == 1) {
						nextBx -= dx[i]; 
						nextBy -= dy[i]; //벽일 경우 이전위치로
					}
					break;
				}
			}

			//red와 blue가 겹칠 경우
			if (nextRx == nextBx and nextRy == nextBy) {
				if (arr[nextRx][nextRy] != 4) {
					int red_dist = abs(nextRx - cur.Rx) + abs(nextRy - cur.Ry);
					int blue_dist = abs(nextBx - cur.Bx) + abs(nextBy - cur.By);

					if (blue_dist > red_dist) {
						nextBx -= dx[i];
						nextBy -= dy[i];
					}
					else {
						nextRx -= dx[i];
						nextRy -= dy[i];
					}
				}
			}

			//방문여부 확인
			if (visited[nextRx][nextRy][nextBx][nextBy] == 0) {
				visited[nextRx][nextRy][nextBx][nextBy] = 1;
				INFO next;
				next.Rx = nextRx;
				next.Ry = nextRy;
				next.Bx = nextBx;
				next.By = nextBy;
				next.count = cur.count + 1;

				bfsQ.push(next);

			}
		}

	}
	return ans;
}

int main() {
	cin >> n >> m;
	string input;

	for (int i = 0; i < n; i++) {
		cin >> input;
		for (int j = 0; j < m; j++) {
			if (input[j] == '#') {
				arr[i][j] = 1;
			}
			else if (input[j] == 'R') {
				arr[i][j] = 2;
				start.Rx = i;
				start.Ry = j;
			}
			else if (input[j] == 'B') {
				arr[i][j] = 3;
				start.Bx = i;
				start.By = j;
			}
			else if (input[j] == 'O') {
				arr[i][j] = 4;
			}
		}
	}
	start.count = 0;
	cout << bfs();
}

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 2638/C++  (0) 2024.11.19
백준 16234 / C++  (0) 2024.08.17
백준 1520 / C++  (0) 2024.08.07
백준 16236  (0) 2024.07.30
백준 9019  (0) 2024.07.16

https://www.acmicpc.net/problem/2638

이 문제의 경우 dfs로 풀이를 진행했다  이 문제를 풀 때 한가지 잘못 생각한점으 치즈 안의 공간은 실내온도에 접촉 한것이아니라는 것이었다.  문제에서 테두리에는 치즈가 없다고 명시해주었으므로 dfs혹은 bfs로 0,0 위치 와 연결된 공간들을 모두 -1  로 체크 해주었다 그후 dfs를 한번더 진행하여 치즈들중 외부공기 2층이랑 이어진 공간들에 대해서 다른 배열에 넣어서 계산해주고 다시 0,0부터 dfs를 돌려 외부공기를 체크해 주었다.

#include <iostream>
using namespace std;
int N, M;
int arr[100][100];
int willMelt[100][100];
int xIdx[4] = { 1,0,-1,0 };
int yIdx[4] = { 0,1,0,-1 };
bool isVisited[100][100] = { 0, };
bool canGo(int x, int y) {
	if (x < N && y < M && x >= 0 && y >= 0) {
		if (!isVisited[x][y] && (arr[x][y] == 1))
			return true;
		else
			return false;
	}
	else
		return false;
}
void copyArr(int arr[100][100], int arr2[100][100]) {
	for (int i = 0; i < N; i++)
		for (int j = 0; j < M; j++) {
			arr[i][j] = arr2[i][j];
		}
}
void dfs(int x, int y) {
	int zeroCount = 0;
	for (int i = 0; i < 4; i++) {
		if (arr[x + xIdx[i]][y + yIdx[i]] == -1) {
			zeroCount += 1;
		}
		if (canGo(x + xIdx[i], y + yIdx[i])) {
			isVisited[x + xIdx[i]][y + yIdx[i]] = true;
			dfs(x + xIdx[i], y + yIdx[i]);
		}
	}
	if (zeroCount >= 2) {
		willMelt[x][y] = 0;
	}

}
void airDfs(int x, int y) {
	arr[x][y] = -1;
	for (int i = 0; i < 4; i++) {
		if (x + xIdx[i] < N && y + yIdx[i] < M && x + xIdx[i] >= 0 && y + yIdx[i] >= 0 && !isVisited[x + xIdx[i]][y + yIdx[i]]&& (arr[x + xIdx[i]][y + yIdx[i]] == 0|| arr[x + xIdx[i]][y + yIdx[i]] == -1)) {
			isVisited[x + xIdx[i]][y + yIdx[i]] = true;
			arr[x + xIdx[i]][y + yIdx[i]] = -1;
			airDfs(x + xIdx[i], y + yIdx[i]);
		}
	}


}
void meltCheese() {
	copyArr(willMelt, arr);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (!canGo(i, j))
				continue;
			isVisited[i][j] = true;
			dfs(i, j);
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			isVisited[i][j] = false;
		}
	}
	copyArr(arr, willMelt);
}
bool isMelted() {
	int sum = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (arr[i][j] != -1)
				sum += 1;
		}
	}
	if (sum == 0)
		return true;
	else
		return false;
}
void process() {
	int year = 0;
	airDfs(0, 0);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			isVisited[i][j] = false;
		}
	}
	while (!isMelted()) {
		meltCheese();
		airDfs(0, 0);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				isVisited[i][j] = false;
			}
		}
		year += 1;
	}
	cout << year;
}
int main() {
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> arr[i][j];
		}
	}
	process();
}

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 13460 / CPP / bfs  (0) 2025.01.14
백준 16234 / C++  (0) 2024.08.17
백준 1520 / C++  (0) 2024.08.07
백준 16236  (0) 2024.07.30
백준 9019  (0) 2024.07.16

https://www.acmicpc.net/problem/16234

이 문제의 경우 bfs 문제이다 dfs로 풀어도 무방하다
나의 경우 이문제를 풀 때 &&의 순서를 잘못 써서 문제를 제출했을 때 틀렸었다

#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
int arr[50][50];
bool isVisited[50][50];
queue<pair<int, int>> bfsq;
queue<pair<int, int>> visitedq;
int n, l, r;
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
bool canGo(int x, int y, int nx, int ny) {
	if (nx >= 0 && nx < n && ny>=0 && ny < n && !isVisited[nx][ny]) {
		if (abs(arr[nx][ny] - arr[x][y])>=l && abs(arr[nx][ny] - arr[x][y])<=r) {
			return true;
		}
		return false;
	}
	else {
		return false;
	}
}
bool bfs(int sX, int sY) {
	bfsq.push({ sX,sY });
	visitedq.push({ sX,sY });
	isVisited[sX][sY] = true;

	int cx, cy , nx, ny ,population, nationCount;
	int avrPop=0;
	population = arr[sX][sY];
	nationCount = 1;
	while (!bfsq.empty()) {
		cx = bfsq.front().first;
		cy = bfsq.front().second;
		bfsq.pop();
		for (int i = 0; i < 4; i++) {
			nx = cx + dx[i];
			ny = cy + dy[i];
			if (canGo(cx, cy, nx,ny)) {
				bfsq.push({ nx, ny });
				visitedq.push({ nx, ny });
				isVisited[nx][ny] = true;
				population += arr[nx][ny];
				nationCount += 1;
			}
		}
	}
	avrPop = population / nationCount;

	while (!visitedq.empty()) {
		arr[visitedq.front().first][visitedq.front().second] = avrPop;
		visitedq.pop();
	}

	if (nationCount > 1)
		return false;
	else {
		isVisited[sX][sY] = false;
		return true;
	}
}
int main() {
	cin >> n >> l >> r;
	int cnt = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> arr[i][j];
		}
	}

	while (true) {
		bool canBreak = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if(!isVisited[i][j])
					canBreak=bfs(i, j)&&canBreak;
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				isVisited[i][j] = false;
			}
		}
		if (canBreak)
			break;
		cnt += 1;
	}
	cout << cnt;

}

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 13460 / CPP / bfs  (0) 2025.01.14
백준 2638/C++  (0) 2024.11.19
백준 1520 / C++  (0) 2024.08.07
백준 16236  (0) 2024.07.30
백준 9019  (0) 2024.07.16

https://www.acmicpc.net/problem/1520

이 문제는 처음에 dfs로 만 풀었으나 시간초과 가 났다 이에 dp와 섞어서 풀어야 한다는 힌트를 보게 되었다

			dp[x][y] = dp[x][y] + dfs(x + xidx[i],y + yidx[i]);

dp의 점화식은 이와 같은데 그이유는 나는 내가 다음에 갈수 있는 경로들이 갈수 있는 경로들의 합으로 표현할수 있기 때문이다

 

나는 dp배열을 -1로초기화를 해주었는데 그이유는 방문하지 않았다는 표시를 -1로 하게되었습니다 0은 방문은 했으나 해당 영역을 통해서 경로를 찾을 수 없는 것이라고 결정 하였습니다. 경로를 탐색하러 들어갔을 때 이미 해당 노드를 방문 한적이 있으면 해당 노드를 통해서 방문했던 길의 갯수가 해당 노드의 저장이 되어있기에 해당 노드의 값을 그대로 반환해주었습니다.

#include <iostream>
#include <set>
using namespace std;
int arr[500][500];
int dp[500][500];
int m, n;
int cnt;
int xidx[4] = { 1,0,-1,0 };
int yidx[4] = { 0,1,0,-1 };
bool canGo(int x, int y, int height) {
	if (x >= 0 && x < m && y>=0 && y < n && height > arr[x][y])
		return true;
	else
		return false;
}

int dfs(int x,int y) {
	if (x == m - 1 && y == n - 1) {
		return 1;
	}
	if (dp[x][y] != -1)
	{
		return dp[x][y];
	}

	dp[x][y] = 0;
	for (int i = 0; i < 4; i++) {
		if (canGo(x + xidx[i], y + yidx[i], arr[x][y])) {
			dp[x][y] = dp[x][y] + dfs(x + xidx[i],y + yidx[i]);
		}
	}
	return dp[x][y];
}
int main() {
	cin >> m >> n;
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			cin >> arr[i][j];
			dp[i][j] = -1;
		}
	}
	cout << dfs(0, 0);
}

전체 로직은 위와 같다

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 2638/C++  (0) 2024.11.19
백준 16234 / C++  (0) 2024.08.17
백준 16236  (0) 2024.07.30
백준 9019  (0) 2024.07.16
백준 1987  (0) 2024.07.16

https://www.acmicpc.net/problem/16236

이 문제는 솔직히 설명이 겁나 불친절하다 

정확히 이문제는 핵심이 나를 기준으로 나보다 크기가 작고 같은 거리에 있는 물고기 들은 위에에서 왼쪽부터 오른쪽 까지 검사하고 내려와서 왼쪽부터 오른쪽 까지 검사하면서 이 순으로 탐색을 하는 거였다.
단 위에를 듣고 BFS  이동방향을 1,0 ->0,-1 ->0,1 ->-1,0 이렇게 만 하면 안풀린다

while (!bfsQ.empty()) {
		
				otherX = bfsQ.front().second.first;
				otherY = bfsQ.front().second.second;
				otherCost = bfsQ.front().first;
				if (CanEat(otherX, otherY) && otherCost<=cost) {
					if (otherX < startX) {
						startX = otherX;
						startY = otherY;
						otherCost = cost;
					}
					else if (otherX == startX && startY>otherY ) {
						startX = otherX;
						startY = otherY;
						otherCost = cost;
					}
				}

핵심은 이부분이다 내가 물고기를 먹을 수있는 지역으로 갔을 때 현재 큐에  들어와 있는 것중 나보다 거리가 작거나 같고 행의 값이  위에 있거나 혹은 행이 같다면 열값이 더 먼저인 애를 찾아서 거기를 가야한다 이에 의해 필자는 행을 검사에서 위에있으면 해당 행으로 탐색지점을 바꿔줬고 같다면 열값이 더 작은 쪽으로 옮겨줬다

#include <iostream>
#include <queue>
using namespace std;
int n;
int arr[20][20] = { 0, };
bool isVisited[20][20];
int fishSize = 2;
int eatFish = 0;
int cnt = 0;
queue<pair<int,pair<int, int>>>  bfsQ;

bool CanEat(int x, int y) {
	if (arr[x][y]>0&&arr[x][y] < fishSize) {
		return true;
	}
	return false;
}
bool canGo(int x, int y) {
	if (x >= 0 && x < n && y >= 0 && y < n && !isVisited[x][y] && (CanEat(x, y) || arr[x][y] == 0 || arr[x][y]==fishSize))
		return true;
	else
		return false;
}

void Bfs(int x, int y) {
	bfsQ.push({ cnt,{x,y} });
	arr[x][y] = 0;
	int startX, startY, cost;
	int otherX, otherY, otherCost;
	while (!bfsQ.empty()) {
		startX = bfsQ.front().second.first;
		startY = bfsQ.front().second.second;
		cost = bfsQ.front().first;
		bfsQ.pop();
		if (CanEat(startX, startY)) {
			cnt += cost;
			while (!bfsQ.empty()) {
		
				otherX = bfsQ.front().second.first;
				otherY = bfsQ.front().second.second;
				otherCost = bfsQ.front().first;
				if (CanEat(otherX, otherY) && otherCost<=cost) {
					if (otherX < startX) {
						startX = otherX;
						startY = otherY;
						otherCost = cost;
					}
					else if (otherX == startX && startY>otherY ) {
						startX = otherX;
						startY = otherY;
						otherCost = cost;
					}
				}

				bfsQ.pop();
				
			}
			bfsQ.push({ 0, {startX, startY}});
			eatFish += 1;
			if (eatFish == fishSize) {
				fishSize += 1;
				eatFish = 0;
			}
			arr[startX][startY] = 0;
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					isVisited[i][j] = false;
				}
			}
			isVisited[startX][startY] = true;
			cost = 0;
		}

		if (canGo(startX-1,startY)) {
			bfsQ.push({ cost + 1,{startX -1,startY}});
			isVisited[startX - 1][startY] = 1;
		}
		if (canGo(startX, startY-1)) {
			bfsQ.push({ cost + 1,{startX ,startY - 1} });
			isVisited[startX][startY-1] = 1;
		}
		if (canGo(startX , startY+1)) {
			bfsQ.push({ cost + 1,{startX ,startY + 1} });
			isVisited[startX][startY + 1] = 1;
		}
		if (canGo(startX+1 , startY)) {
			bfsQ.push({ cost + 1,{startX + 1,startY} });
			isVisited[startX + 1][startY] = 1;
		}
	}

}
int main() {
	cin >> n;
	int startIdxCol, startIdxRow;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> arr[i][j];
			if (arr[i][j] == 9) {
				startIdxCol = i;
				startIdxRow = j;
			}
		}
	}

	Bfs(startIdxCol, startIdxRow);
	cout << cnt;
}

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 16234 / C++  (0) 2024.08.17
백준 1520 / C++  (0) 2024.08.07
백준 9019  (0) 2024.07.16
백준 1987  (0) 2024.07.16
프로그래머스 PCCP 기출 2  (2) 2024.01.03

 

#include <queue>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int a, b;
bool visited[10000];
int logicD(int num) {
    return (num * 2) % 10000;
}

int logicS(int num) {
    return num - 1 < 0 ? 9999 : num - 1;
}

int logicL(int num) {
    return (num % 1000) * 10 + (num / 1000);
}

int logicR(int num) {
    return num / 10 + (num % 10) * 1000;
}
void bfs()
{
    queue<pair<int, string>> q;
    q.push(make_pair(a, ""));
    visited[a] = true;

    while (!q.empty())
    {
        int cur_num = q.front().first;
        string cur_op = q.front().second;
        q.pop();

        if (cur_num == b)
        {
            cout << cur_op << '\n';
            return;
        }

        int D, S, L, R;
        D = logicD(cur_num);
        if (!visited[D])
        {
            visited[D] = true;
            q.push(make_pair(D, cur_op + "D"));
        }
        S = logicS(cur_num);
        if (!visited[S])
        {
            visited[S] = true;
            q.push(make_pair(S, cur_op + "S"));
        }
        L = logicL(cur_num);
        if (!visited[L])
        {
            visited[L] = true;
            q.push(make_pair(L, cur_op + "L"));
        }
        R = logicR(cur_num);
        if (!visited[R])
        {
            visited[R] = true;
            q.push(make_pair(R, cur_op + "R"));
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int T;
    cin >> T;

    while (T--)
    {
        cin >> a >> b;
        memset(visited, false, sizeof(visited)); // 초기화
        bfs();
    }

    return 0;
}

https://www.acmicpc.net/problem/9019

이 문제는 최소시간을 구하는 것이기에 BFS로 조건을 만족시켰을 경우 바로 출력할 수있도록 코드를 작성하여야 합니다

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 1520 / C++  (0) 2024.08.07
백준 16236  (0) 2024.07.30
백준 1987  (0) 2024.07.16
프로그래머스 PCCP 기출 2  (2) 2024.01.03
[CPP] 백준 11403  (0) 2023.10.26

https://www.acmicpc.net/problem/1987

이 문제의 경우 그냥 쉬운 DFS였다 골드 4라고하기에는 많이 애매한 문제라고 생각되어진다.
DFS와 단짝인 백트래킹과 조건 검사식만 설정해주면 되는 문제였다.

 

#include<iostream>
using namespace std;
int isVisited[20][20];
bool isUsed[26];
char arr[20][20];
int maxNum = 0;
int GetIdxOfAlphabet(char ch);
bool isCanGo(int idxX, int idxY) {
	if (idxX < 0 || idxY < 0 || idxX>19 || idxY > 19 || (isVisited[idxX][idxY] == true) || (isUsed[GetIdxOfAlphabet(arr[idxX][idxY])]==true)) {
		return false;
	}

	return true;
}
void dfs(int startX, int startY, int cnt) {
	if (!isCanGo(startX, startY)) {
		if (cnt-1 > maxNum) {
			maxNum=cnt-1;
			return;
		}
	}
	else {
		isUsed[GetIdxOfAlphabet(arr[startX][startY])] = true;
		isVisited[startX][startY] = true;
		dfs(startX + 1, startY, cnt + 1);
		dfs(startX -1, startY, cnt + 1);
		dfs(startX, startY+1, cnt + 1);
		dfs(startX, startY-1, cnt + 1);
		isUsed[GetIdxOfAlphabet(arr[startX][startY])] = false;
		isVisited[startX][startY] = false;
	}
}

int GetIdxOfAlphabet(char ch) {
	if (ch >= 'A' && ch <= 'Z') {
		int position = ch - 'A';
		return position;
	}
	else
		return 0;
}
int main() {
	int r, c;
	cin >> r >> c;
	char inputString[21];
	for (int i = 0; i < r; i++) {
		cin >> inputString;
		for (int j = 0; j < c; j++) {
			arr[i][j] = inputString[j];
		}
	}
	dfs(0, 0, 1);
	cout << maxNum;
	return 0;
}

 

이 문제의 경우 입력 string으로 받을 시 문제가 생겨서 해당 부분을 char 배열을 입력받도록 변경하였습니다.
또한 항상 이전에 dfs를 풀때 조건식을 위에다가사용했을 때 너무 복잡해지는 현상이 있어 함수로 해당 부분을 따로 정ㄴ리해 놓았습니다

 

DFS에서 항상 중요한건 방문했다가 나오면 다시 배열들을 초기화 해줘야 한다는 것입니다

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 16236  (0) 2024.07.30
백준 9019  (0) 2024.07.16
프로그래머스 PCCP 기출 2  (2) 2024.01.03
[CPP] 백준 11403  (0) 2023.10.26
백준 10026  (1) 2023.10.25

 

https://school.programmers.co.kr/learn/courses/30/lessons/250136

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

이 문제는 간단한 문제인줄 알고 건드렸다가 2시간을 날릴 정도로 고생한 문제이다 
일단 이 문제의경우 딱 봤을 때 BFS를 사용하는거는 확실 해 보이지만 매번 시추할 때 마다 BFS를 돌리면 효율성 검사에서 점수가 떨어지게 된다 이에 이문제는 BFS를 이용해서 뽑아낸 데이터를 어떤 자료 구조에 넣어 사용하는 지가 매우 중요한 문제이다

#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
int directionX[4] = { 1, 0, -1, 0 };
int directionY[4] = { 0, 1, 0, -1 };
int isVisited[501][501] = { 0, };
map<int, int> sizeOfOil;
int sizeOfLandX;
int sizeOfLandY;
int areaNum = 1;
vector<vector<int>> oilMap;
void BFS(int startX, int startY ) {
    int tmp = 0;
    queue<pair<int, int>> q;
    q.push({ startX, startY });
    oilMap[startX][startY] = areaNum;
    isVisited[startX][startY] = 1;
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        tmp++;
        q.pop();

        for (int i = 0; i < 4; i++) {
            int nextX = x + directionX[i];
            int nextY = y + directionY[i];
            if (nextX >= 0 && nextX < sizeOfLandX && nextY >= 0 && nextY < sizeOfLandY && isVisited[nextX][nextY] == false && oilMap[nextX][nextY]>0) {
                oilMap[nextX][nextY] = areaNum;
                isVisited[nextX][nextY] = 1;
                q.push({ nextX,nextY });
            }
        }
    }
    sizeOfOil[areaNum] = tmp;
    areaNum++;
   
}
int solution(vector<vector<int>> land) {
    int answer = 0;
    oilMap = land;
    sizeOfLandX = land.size(); //열의 길이
    sizeOfLandY = land[0].size(); //행의 길이

    for (int i = 0; i < sizeOfLandX; i++) {
        for (int j = 0; j < sizeOfLandY; j++) {
            if (isVisited[i][j] == false && land[i][j] == 1) {
                BFS(i, j);
            }
        }
    }

    for (int j = 0; j < sizeOfLandY; j++) {
        set<int> oilSet;
        int sumOfOil=0;
        for (int i = 0; i < sizeOfLandX; i++) {
            oilSet.insert(oilMap[i][j]);
        }
        set<int>::iterator iter;
        for (auto it : oilSet) {
            sumOfOil += sizeOfOil[it];
        }
        answer = max(answer, sumOfOil);
    }

    return answer;
}

일단 이 문제의 경우 내가 블로그에 기존에 올렸던 BFS보다 간단 하다 원래는 Direction을 일일히 내가 정해줬었는데 이를 배열에 넣어 간단하게 보이게 했다. 코드 가독성이 올라가니 확실히 디버깅 효율이 올라갔다

자 일단 이문제의 핵심로직은 BFS로 구해놓은 영역의 유전의 크기를 영역별로 들고 있어야 한다 이를 위해 위 코드에

void BFS(int startX, int startY ) {
    int tmp = 0;
    queue<pair<int, int>> q;
    q.push({ startX, startY });
    oilMap[startX][startY] = areaNum;
    isVisited[startX][startY] = 1;
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        tmp++;
        q.pop();

        for (int i = 0; i < 4; i++) {
            int nextX = x + directionX[i];
            int nextY = y + directionY[i];
            if (nextX >= 0 && nextX < sizeOfLandX && nextY >= 0 && nextY < sizeOfLandY && isVisited[nextX][nextY] == false && oilMap[nextX][nextY]>0) {
                oilMap[nextX][nextY] = areaNum;
                isVisited[nextX][nextY] = 1;
                q.push({ nextX,nextY });
            }
        }
    }
    sizeOfOil[areaNum] = tmp;
    areaNum++;
   
}

BFS 부분에서sizeOfOil에 저장해 주었다 여기서 sizeOfOil은 맵 자료형이다 맵자료형은 map<int,int>이렇게 사용했을 때 맨앞에 오는 값은 Key로서 두번쨰 오는 값은 value로 써 작용합니다.
즉 map<key, value> 의 형태로 각각의 해당하는 자료형을 넣어주면 됩니다 .

 

이 문제에서는 Map의 저장해놓은 데이터를 순환하여 찾아와야 하기 때문에

for (auto iter = m.begin() ; iter !=  m.end(); iter++)
{
	cout << iter->first << " " << iter->second << endl;
}
cout << endl;

의 형태와

for (auto iter : m) {
	cout << iter.first << " " << iter.second << endl;
}

의 형태의 두가지 형태로 map을 순환 할 수 있습니다.
이에 필자는 두번째 형태로 사용하였습니다. 

이렇게 Map형태로 저장해놓은 데이터에서 우리는 land 배열에 새로줄에서 만나는 areaNum들을 set에 넣어줍니다.
Set은 마찬가지로 중복되는 자료를 넣으면 넣지 않기 때문에 areaNum을 최대 1번씩만 넣을 수 있습니다
이에 set.insert를 이용해서 각 세로줄에 있는 유전의 areaNum을 넣습니다.

그후 이를 순회하면서 areaNum을 통해 세로줄에 있는 해당 유전에 크기를 더하여 최대값을 출력합니다

'백준(코테준비) > DFS,BFS' 카테고리의 다른 글

백준 9019  (0) 2024.07.16
백준 1987  (0) 2024.07.16
[CPP] 백준 11403  (0) 2023.10.26
백준 10026  (1) 2023.10.25
백준 16928  (0) 2023.10.21

+ Recent posts