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

이 문제는 그냥 여러개 섞어놓은 문제이다 병사를 배정하는것은 조합으로 dfs로 풀면 되고 
병사들이 몬스터를 잡는건 bfs로 풀면된다 조합에대한 모든것을 bfs함으로 브루트포스이기도 하다 사실이문제는 단지 기본적인 알고리즘 여러개를 섞어놓은것이다
주의할 점은 bfs를 할때

int goX[3] = { 0,-1,0};
int goY[3] = { -1,0,1};

이 순서대로 해야한다 bfs가 거리가 가까운거는 보장하지만 왼쪽 탐색을 하기위해서는 해당 인덱스를 따라 해야지 왼쪽부터 탐색한다
또한 탐색하자마자 바로 0으로 바꾸지말고 중복으로 한 몬스터를 때릴수 있으므로 4로 체크하고 이후에 0으로 바꾼다

#include <iostream>
#include <stdlib.h>
#include <queue>
using namespace std;
int originArr[16][15];
int copyArr[16][15];
int N, M, D;
int goX[3] = { 0,-1,0};
int goY[3] = { -1,0,1};
int maxNum;
bool isVisited[16][15] = { 0, };
bool AllDie() {
	bool isDie = true;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (copyArr[i][j] == 1)
				isDie = false;
		}
	}
	return isDie;
}
void CopyOrigin() {
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j < M; j++) {
			copyArr[i][j] = originArr[i][j];
		}
	}
}
bool CanGo(int x, int y) {
	if (x >= 0 && x < N && y >= 0 && y < M ) {
		return true;
	}
	else {
		return false;
	}
}
void downEnemy() {
	for (int i = N-1 ; i > 0; i--) {
		for (int j = 0; j < M; j++) {
			copyArr[i][j] = copyArr[i - 1][j];
			if (copyArr[i][j] == 4)
				copyArr[i][j] = 0;
		}
	}
	for (int i = 0; i < M; i++) {
		copyArr[0][i] = 0;
	}
}
int bfs(int armyX, int armyY) {
	queue<pair<int, pair<int, int>>> ArmyQ;
	ArmyQ.push({ 0,{armyX,armyY} });
	int count = 0;
	while (!ArmyQ.empty()) {
		int curX = ArmyQ.front().second.first;
		int curY = ArmyQ.front().second.second;
		int cost = ArmyQ.front().first;
		ArmyQ.pop();
		if (cost > D)
			break;
		if (copyArr[curX][curY] == 4) {
			break;
		}
		if (copyArr[curX][curY] == 1) {
			copyArr[curX][curY] = 4;
			count += 1;
			break;
		}

		for (int i = 0; i < 3; i++) {
			int nextX = curX + goX[i];
			int nextY = curY + goY[i];
			if (CanGo(nextX, nextY)) {
				ArmyQ.push({ cost + 1,{nextX,nextY} });
			}
		}
	}
	return count;
}
void dfs(int start, int count) {
	if (count == 3) {// 병사를 3명 다배치 했을 경우
		CopyOrigin();
		int num = 0;
		while (!AllDie()) {
			for (int i = 0; i < M; i++) {
				if (copyArr[N][i] == 3) {
					num += bfs(N, i);
				}
			}
			downEnemy();
		}
		maxNum = max(num, maxNum);
	}
	
	else {
		for (int i = start+1; i < M; i++) {
			originArr[N][i] = 3;
			dfs(i, count + 1);
			originArr[N][i] = 2;
		}
	}
}
int main() {
	cin >> N >> M >> D;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> originArr[i][j];
		}
	}
	for (int i = 0; i < M; i++) {
		originArr[N][i] = 2;
	}
	for (int i = 0; i < M; i++) {
		originArr[N][i] = 3;
		dfs(i, 1);
		originArr[N][i] = 2;
	}
	cout << maxNum;
}

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 12100  (0) 2024.12.06
백준 2589 / CPP  (0) 2024.11.29
백준 1038  (0) 2024.11.26
백준 14500  (0) 2024.07.30

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

문제가 개노가다다 생각 하고 구현하기는 쉬운데 매우 귀찮다 로직은 간단 하다
위로 올릴 경우 내위에 애와 내가 같으면  위에 애를  *  2 하고 그리고 이동 시켰다고 체크 한후 
이동 시킨애는 위로 이동 됬을 거니 굳이 이후 배열에 값을 넣어 주지 않는다.

#include <iostream>
#include <algorithm>
#include <cstring> // For memset
using namespace std;

int n;
int arr[20][20];
int maxBlock = 0;

// 배열 이동 처리 (상하좌우)
void moveArray(int dir, int beforeArr[20][20], int afterArr[20][20]) {
    memset(afterArr, 0, sizeof(int) * 20 * 20); // 결과 배열 초기화
    bool isCombined[20][20] = { false }; // 블록 합쳐진 상태 확인

    if (dir == 0) { // 위로 이동
        for (int j = 0; j < n; j++) {
            int target = 0; // 이동 시킬 애
            for (int i = 0; i < n; i++) {
                if (beforeArr[i][j] == 0) continue;
                if (target > 0 && afterArr[target - 1][j] == beforeArr[i][j] && !isCombined[target - 1][j]) {
                    afterArr[target - 1][j] *= 2;
                    isCombined[target - 1][j] = true;
                }
                else {
                    afterArr[target++][j] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 1) { // 아래로 이동
        for (int j = 0; j < n; j++) {
            int target = n - 1; // 이동 시킬 애
            for (int i = n - 1; i >= 0; i--) {
                if (beforeArr[i][j] == 0) continue;
                if (target < n - 1 && afterArr[target + 1][j] == beforeArr[i][j] && !isCombined[target + 1][j]) {
                    afterArr[target + 1][j] *= 2;
                    isCombined[target + 1][j] = true;
                }
                else {
                    afterArr[target--][j] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 2) { // 왼쪽으로 이동
        for (int i = 0; i < n; i++) {
            int target = 0;// 이동 시킬 애
            for (int j = 0; j < n; j++) {
                if (beforeArr[i][j] == 0) continue;
                if (target > 0 && afterArr[i][target - 1] == beforeArr[i][j] && !isCombined[i][target - 1]) {
                    afterArr[i][target - 1] *= 2;
                    isCombined[i][target - 1] = true;
                }
                else {
                    afterArr[i][target++] = beforeArr[i][j];
                }
            }
        }
    }
    else if (dir == 3) { // 오른쪽으로 이동
        for (int i = 0; i < n; i++) {
            int target = n - 1; // 이동 시킬 애
            for (int j = n - 1; j >= 0; j--) {
                if (beforeArr[i][j] == 0) continue;
                if (target < n - 1 && afterArr[i][target + 1] == beforeArr[i][j] && !isCombined[i][target + 1]) {
                    afterArr[i][target + 1] *= 2;
                    isCombined[i][target + 1] = true;
                }
                else {
                    afterArr[i][target--] = beforeArr[i][j];
                }
            }
        }
    }
}

// 재귀적으로 모든 경우 탐색
void solve(int cnt, int beforeArr[20][20]) {
    if (cnt == 6) {
        // 최댓값 갱신
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                maxBlock = max(maxBlock, beforeArr[i][j]);
            }
        }
        return;
    }

    for (int dir = 0; dir < 4; dir++) { // 네 방향으로 이동
        int afterArr[20][20];
        moveArray(dir, beforeArr, afterArr);
        solve(cnt + 1, afterArr);
    }
}

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

    solve(0, arr);
    cout << maxBlock << endl;
    return 0;
}

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 17135 / C++ / dfs / bfs / 브루트 포스  (0) 2025.01.12
백준 2589 / CPP  (0) 2024.11.29
백준 1038  (0) 2024.11.26
백준 14500  (0) 2024.07.30

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

이 문제의 경우 브루트 포스긴 하나 모든 경우의 수에 대해 bfs를 이용해서 푸는 문제였다 bfs를 브루트포스하여 푸는 문제니 부르트포스 문제일 수도 있고 bfs 문제일 수도 있다 이문제의 경우 bfs를 구현할 줄 알면 큰  문제가 없다 본인의 경우 2%의  오류가 났었는데 해당 이유는 처음 bfs를 실행할 때 해당 위치가 'W'인지를 검사 하지 않아서 발생 했었다

#include<iostream>
#include<queue>
using namespace std;
int n, m;
char arr[50][50];
int isVisited[50][50] = { 0, };
int maxLength=0;
queue<pair<int, int>>bfsQ;
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,-1,0,1 };
bool canGo(int x, int y) {
	if (x >= 0 && x < n && y >= 0 && y < m && !isVisited[x][y] && arr[x][y]=='L')
		return true;
	else
		return false;
}
void bfs(int sx, int sy) {
	bfsQ.push({ sx,sy });
	isVisited[sx][sy] = 1;
	while (!bfsQ.empty()) {
		int sx = bfsQ.front().first;
		int sy = bfsQ.front().second;
		int distance = isVisited[sx][sy];
		bfsQ.pop();
		for (int i = 0; i < 4; i++) {
			if (canGo(sx + dx[i], sy + dy[i])) {
				bfsQ.push({sx + dx[i],sy + dy[i]});
				isVisited[sx + dx[i]][sy + dy[i]] = distance + 1;
			}
		}
	}
}
int getMaxValue() {
	int maxValue=0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			maxValue=max(maxValue, isVisited[i][j]);
		}
	}
	return maxValue-1;
}
void InitIsVisited() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			isVisited[i][j] = 0;
		}
	}
}
int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> arr[i][j];
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (canGo(i, j)) {
				bfs(i, j);
				maxLength = max(maxLength, getMaxValue());
				InitIsVisited();
			}
		}
	}
	cout << maxLength;
}

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 17135 / C++ / dfs / bfs / 브루트 포스  (0) 2025.01.12
백준 12100  (0) 2024.12.06
백준 1038  (0) 2024.11.26
백준 14500  (0) 2024.07.30

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

이 문제의 경우 문제 분류에 부르트 포스 라고 되어있지만 정확히는 dfs 백트래킹이라고 보는게 맞을거 같다 
처음에는 0 부터 9876543210 까지 수들을 검사해서 해당 수가 감소하는 수 인지를 검사하는 방법을 사용했지만 해당 방법은 시간초과를 유발했기에 dfs와 백트래킹을 사용하여 해당 문제를 풀었다

해당 이미지를 보자 우리가 백트래킹으로감소하는 수를 만들려고 할시 반복문의 범위를 단지 이전 자리의 숫자의 값까지만 증가시켜주면서 넣어주면 된다

#include <iostream>
using namespace std;
long  long arr[1000001];
long  long n;
long  long numCnt;
long  long idxOfNum = 10;
void makeDecreaseNum(long  long num , long  long numOfone , long  long cntOfNum) {
	if (cntOfNum==numCnt) {
		arr[idxOfNum] = num;
		idxOfNum++;
	}
	else {
		num = num * 10;
		for (long  long i = 0; i < numOfone; i++) {
			makeDecreaseNum(num + i, i, cntOfNum+1);
		
		}
	}

}
int main() {
	cin >> n;
	for (long  long i = 0; i < 1000001; i++) {
		arr[i] = -1;
	}
	for (long  long i = 0; i < 10; i++) {
		arr[i] = i;
	}
	for (long  long i = 2; i <= 11; i++) {
		numCnt = i;
		for (long  long j = 1; j <= 9; j++) {
			makeDecreaseNum(j, j, 1);
		}
	}
	cout << arr[n];
}

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 17135 / C++ / dfs / bfs / 브루트 포스  (0) 2025.01.12
백준 12100  (0) 2024.12.06
백준 2589 / CPP  (0) 2024.11.29
백준 14500  (0) 2024.07.30

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

이 문제의  경우 나는 일단 dfs와 ㅗ 모양의 블록을 나눠서 풀었다 .

테트로미노에는 이렇게 현재 블럭이 있는데

빨간색을 제외한 블록들은 dfs로 검색하면 회전까지 나오는 모양 들이다 빨간색으로 둘러싼 모형들을 배열에다 다 넣어서 최대값을 구하는게 해당 문젠데 그후 빨간색으로 둘러친걸 넣어보면서 최대값을 구하면 된다

 

일단 빨간색을 제외한 코드의 부분은

void dfs(int x, int y, int cnt , int sum) {
	if (cnt == 4) {
		if (sum > maxNum) {
			maxNum = sum;
		}
	}
	else {
		if (canGo(x + 1, y)) {
			isVisited[x + 1][y] = true;
			dfs(x + 1, y, cnt + 1, sum + arr[x+1][y]);
			isVisited[x + 1][y] = false;
		}
		if (canGo(x - 1, y)) {
			isVisited[x - 1][y] = true;
			dfs(x - 1, y, cnt + 1, sum + arr[x-1][y]);
			isVisited[x - 1][y] = false;
		}
		if (canGo(x , y+1)) {
			isVisited[x][y+1] = true;
			dfs(x , y+1, cnt + 1, sum + arr[x][y+1]);
			isVisited[x][y + 1] = false;
		}
		if (canGo(x , y-1)) {
			isVisited[x ][y-1] = true;
			dfs(x , y-1, cnt + 1, sum + arr[x][y-1]);
			isVisited[x][y - 1] = false;
		}
	}
}

이렇게 된다 그이이유는 저위에 빨간색을 제외한 부분들을 회전과 대칭을 고려할경우 dfs로 나오는 모형과 똑같기 떄문이다
그후 빨간색으로 둘러쳐진 모양은 노가다를 했다

void mountatinShape(int startX, int startY) {
	if (canGo(startX + 1, startY) && canGo(startX, startY - 1) && canGo(startX,startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX][startY - 1] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
	if (canGo(startX - 1, startY) && canGo(startX, startY - 1) && canGo(startX, startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX - 1][startY] + arr[startX][startY - 1] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}

	if (canGo(startX + 1, startY) && canGo(startX -1, startY) && canGo(startX, startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX-1][startY] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
	if (canGo(startX + 1, startY) && canGo(startX - 1, startY) && canGo(startX, startY - 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX - 1][startY] + arr[startX][startY - 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
}

그래서 이두 로직을 합치면서 최댓값을 저장해주면 이문제는 해결이다

#include<iostream>
using namespace std;
int n, m;
int arr[500][500];
bool isVisited[500][500] = { 0, };
int maxNum = 0;
//세로 1자
bool canGo(int px, int py) {
	if (px >= 0 && px < n && py >= 0 && py < m && !isVisited[px][py]) {
		return true;
	}
	else
		return false;
}
void dfs(int x, int y, int cnt , int sum) {
	if (cnt == 4) {
		if (sum > maxNum) {
			maxNum = sum;
		}
	}
	else {
		if (canGo(x + 1, y)) {
			isVisited[x + 1][y] = true;
			dfs(x + 1, y, cnt + 1, sum + arr[x+1][y]);
			isVisited[x + 1][y] = false;
		}
		if (canGo(x - 1, y)) {
			isVisited[x - 1][y] = true;
			dfs(x - 1, y, cnt + 1, sum + arr[x-1][y]);
			isVisited[x - 1][y] = false;
		}
		if (canGo(x , y+1)) {
			isVisited[x][y+1] = true;
			dfs(x , y+1, cnt + 1, sum + arr[x][y+1]);
			isVisited[x][y + 1] = false;
		}
		if (canGo(x , y-1)) {
			isVisited[x ][y-1] = true;
			dfs(x , y-1, cnt + 1, sum + arr[x][y-1]);
			isVisited[x][y - 1] = false;
		}
	}
}

void mountatinShape(int startX, int startY) {
	if (canGo(startX + 1, startY) && canGo(startX, startY - 1) && canGo(startX,startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX][startY - 1] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
	if (canGo(startX - 1, startY) && canGo(startX, startY - 1) && canGo(startX, startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX - 1][startY] + arr[startX][startY - 1] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}

	if (canGo(startX + 1, startY) && canGo(startX -1, startY) && canGo(startX, startY + 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX-1][startY] + arr[startX][startY + 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
	if (canGo(startX + 1, startY) && canGo(startX - 1, startY) && canGo(startX, startY - 1) && canGo(startX, startY)) {
		int sum = 0;
		sum = arr[startX + 1][startY] + arr[startX - 1][startY] + arr[startX][startY - 1] + arr[startX][startY];
		if (sum > maxNum)
			maxNum = sum;
	}
}
void tet1(int startX, int startY) {
	isVisited[startX][startY] = true;
	dfs(startX, startY, 1,arr[startX][startY]);
	isVisited[startX][startY] = false;

}

int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> arr[i][j];
		}
	}

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			mountatinShape(i, j);
			tet1(i, j);
		}
	}

	cout << maxNum;
}

 

'백준(코테준비) > 브루트포스' 카테고리의 다른 글

백준 17135 / C++ / dfs / bfs / 브루트 포스  (0) 2025.01.12
백준 12100  (0) 2024.12.06
백준 2589 / CPP  (0) 2024.11.29
백준 1038  (0) 2024.11.26

+ Recent posts