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

 

1932번: 정수 삼각형

첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.

www.acmicpc.net

1. 풀이방법

- 최대 깊이가 500입니다.

 

- 모든 경우의 수를 모두 구하면 매우 커짐을 알 수 있습니다.

 

- 점화식을 세우고, 0과 i==j 일때 (한변에서 양 끝은 선택권이 한개씩 뿐) 처리를 따로 해주시면 됩니다.

 

- 바텀업 방식으로 작성했습니다.

 

 

2. 주의사항

- 없음

 

 

3. 나의코드

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;

int triangle[500][500];
int dp[500][500];
int n;
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < i + 1; j++) {
			cin >> triangle[i][j];
			dp[i][j] = -1;
		}
	}
	dp[0][0] = triangle[0][0];
	
	for (int i = 1; i < n; i++) {
		for (int j = 0; j < i + 1; j++) {
			if (j == 0) {
				dp[i][j] = dp[i - 1][j] + triangle[i][j];
			}
			else if (j == i) {
				dp[i][j] = dp[i - 1][j - 1] + triangle[i][j];
			}
			else {
				dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j];
			}
		}
	}
	int maxr = -1;
	for (int i = 0; i < n; i++) {
		maxr = max(dp[n - 1][i], maxr);
	}
	cout << maxr << "\n";
	return 0;
}

'알고리즘 문제풀이 > 다이나믹 프로그래밍' 카테고리의 다른 글

백준 3687 [C++]  (0) 2021.08.09
백준 1103 [C++]  (0) 2021.07.06
백준 1793 [C++]  (0) 2021.02.04
백준 1965 [C++]  (0) 2021.02.03
백준 1463 [C++] - 메모리초과  (0) 2020.12.15

www.acmicpc.net/problem/1051

 

1051번: 숫자 정사각형

N*M크기의 직사각형이 있다. 각 칸은 한 자리 숫자가 적혀 있다. 이 직사각형에서 꼭짓점에 쓰여 있는 수가 모두 같은 가장 큰 정사각형을 찾는 프로그램을 작성하시오. 이때, 정사각형은 행 또는

www.acmicpc.net

1. 풀이방법.

 

- 모든 정사각형의 4개의 꼭지점이 같은지 확인해주시면 됩니다.

 

- 입력이 붙어있길래 전 char 배열을 선언해서 입력을 받았습니다.

 

- 숫자가 들어오지만 , 계산하는 과정은 없고 같은지만 확인하면 되므로 따로 숫자로 변환시키지는 않았습니다.

 

 

 

 

2. 주의사항

 

- 하나짜리도 정사각형 입니다. (어찌보면 당연)

 

- 전그냥 따로 예외로 빼주었습니다. 

 

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;

int N, M;
char nemo[51][51]; //0~ n-1, 0 ~ m-1

int maxcnt = 0;

void inputs() {
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> nemo[i][j];
		}
	}
}
int samenemo(int x, int y, int c) {
	if (nemo[x][y] == nemo[x + c][y] && nemo[x][y] == nemo[x][y + c]
		&& nemo[x][y] == nemo[x + c][y + c]) return true;
	else return false;
}
void makecase(int cnt)
{
	for (int i = 0; i < N-cnt; i++) {
		for (int j = 0; j < M-cnt; j++) {
			if (samenemo(i, j,cnt)) {
				if (maxcnt < cnt) {
					maxcnt = cnt;
				}
			}
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	if (N == 1 || M == 1) { cout << 1 << "\n"; return 0; }
	for (int i = 1; i < min(N, M); i++) {
		makecase(i); // 시작 index와 한 변의 길이
	}
	cout << (maxcnt+1)*(maxcnt+1) << "\n";

	return 0;
}

 

www.acmicpc.net/problem/9663

 

9663번: N-Queen

N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

1. 풀이방법

 

- N개의 퀸을 놓을 수 있는 경우의 수 를 구하는 문제이고, 모든 경우의 수를 탐색하는데 시간을 신경써야합니다.

 

- 처음에는 그냥 dx[8],dy[8] 을 선언해서 8방향을 모두 탐색하다가 이미 다른 퀸이 있으면 리턴하고 라는 식으로

 

- 구현을 했다가.....N=5일때 까지 였나...? 까지 밖에 나오지 않았습니다...

 

- 처음에 N이 최대 14이길래 시간초과는 신경 안써도 되는 줄 알고 짰다가 당황한 문제였습니다.

 

- 체스판의 특성을 이용하여 x,y좌표의 특징들을 이용해서 놓을 수 있는지를 판단해야 했습니다.

 

 

 

 

 

2. 주의사항

 

- 체스판의 특성을 활용, 시간초과를 주의해야 함.

 

- 2차원 배열이 아닌 1차원배열을 이용하여 [x]=y를 통해 x,y 좌표를 나타내는 것이 처음에는 생소할 수 있음

 

 

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int N;
int resultcount = 0;
int queenarr[15]; //[x]= y
 // 0~ N-1까지 사용
bool checking(int x, int y) {
	for (int i = 0; i < x; i++) {
		if ( abs(y-queenarr[i]) == abs(x -i) || queenarr[i] == y) {
			return false;
		}
	}
	return true;
}
void makecase(int x) {
	if (x == N) {
		resultcount++; return;
	}
	for (int i = 0; i < N; i++) {
		if (checking(x, i)) {
			queenarr[x] = i;
			makecase(x + 1);
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N;
	makecase(0);
	cout << resultcount << "\n";
	return 0;
}

'알고리즘 문제풀이 > 완탐' 카테고리의 다른 글

백준 2422 [C++] - 시간초과  (0) 2021.01.15
백준 18511 [C++]  (0) 2021.01.15
백준 1107 [C++]  (0) 2020.12.14
백준 14500 [C++]  (0) 2020.12.05
백준 17135 [C++]  (0) 2020.10.21

www.acmicpc.net/problem/1107

 

1107번: 리모컨

첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다.  둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼

www.acmicpc.net

1. 풀이방법

 

- 개인적으로 참 어려웠던 문제였습니다...

 

- 처음에는 경우의 수를 나눠서 1번 (+,-만으로만 접근) 2번 (버튼만으로 접근이 가능한 경우) 3번 (버튼으로 근접하게 간 후 +,- 로 이동해야하는 경우) 3가지 중 min 값을 출력하자 라고 했습니다.

 

- 하지만 저 3번....! 저걸 찾아내는게 굉장히 까다로웠습니다. 숫자를 하나씩 맞춰본다거나, 

  고장난 버튼이면 최대한 근접한 버튼을 누르는데 위,아래 어느 숫자쪽으로 탐색을 해야하나....

 

- 하나의 아이디어를 준 것은 바로 +,-는 마지막에 눌러진다는 것입니다. +,- 버튼을 누르고 나서 숫자를 누를경우 

  처음 부터 다시 숫자를 매겨야 하죠 (보통의 리모컨을 생각해 보시면 될 것 같습니다.)

 

- 그래서 생각해낸 것은 바로.....!

 

- 1. 일단 -1로 모든번호를 저장할 테이블들을 모두 초기화 ! (위로 갔다가 -로 돌아오는 경우도 있으므로 백만까지)

 

- 2. 버튼으로 이동할 수 있는 번호의 경우 테이블에 미리 다 몇번의 버튼을 눌러서 갈 수 있는지 저장!!!!

 

- 3. 찾고자 하는 채널이 -1, 즉 버튼만으로 갈 수 없는 경우 위,아래로 탐색해서 가장 가까이 있는 버튼으로 갈 수 있는

      번호를 찾는다 !!!!!!

( 물론 상기의 과정 중 +,- 버튼만으로 가는 것이 더 적은 수로 이동할 수 있는 경우 그 숫자를 넣어줘야 합니다.)

 

 

 

 

2. 주의사항

 

- 리모콘은 고장나면 쫌 사자.....

 

 

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;

int N,M;
int remote[10]; //0~9
int casestore[1000001];
int len;

bool onlynum(int num) {
	len = 0;
	int tmp = num;
	while (1) {
		if (remote[tmp % 10] == true) return false; //고장나서 버튼만으로는 이동불가
		tmp /= 10;
		len++;
		if (tmp == 0) break;
	}
	return true;
}
void inputs() {
	cin >> N >> M;
	int tmp;
	for (int i = 0; i < M; i++) {
		cin >> tmp;
		remote[tmp] = true; //true는 고장
	}
}
void makecase() {
	casestore[100] = 0;
	for (int i = 0; i < 1000001; i++) {
		if (i == 100) continue;
		if(onlynum(i)==true)
		{
			casestore[i] = min(abs(i - 100), len);
		}
	}
}
void setcase() {
	for (int i = 0; i < 1000001; i++) {
		casestore[i] = -1;
	}
}


int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	setcase();
	makecase();

	if (N == 100) { cout << 0 << "\n"; return 0; }
	if(casestore[N]!=-1){
		cout << casestore[N] << "\n"; return 0;
	}
	else{
		int index = 1;
		while (1) {
			if (N - index >= 0) {
				if (casestore[N - index] != -1) {
					cout << min(abs(N - 100),casestore[N - index] + index) << "\n";
					return 0;
				}
			}
			if (N + index <= 1000000) {
				if (casestore[N + index] != -1) {
					cout << min(abs(N - 100),casestore[N + index] + index) << "\n";
					return 0;
				}
			}
			index++;
		}
	}
	return 0;
}

'알고리즘 문제풀이 > 완탐' 카테고리의 다른 글

백준 18511 [C++]  (0) 2021.01.15
백준 9663 [C++]  (0) 2021.01.13
백준 14500 [C++]  (0) 2020.12.05
백준 17135 [C++]  (0) 2020.10.21
백준 17136 [C++]  (0) 2020.10.20

www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감

www.acmicpc.net

1. 풀이방법.

 

- 전 깊이우선탐색(DFS)로 구현하여 해결하였습니다.

 

- 깊이우선 탐색을 통해 결국 모든 경우의 수를 모두 확인하는 방식입니다.

 

- 먼저 카메라를 carr벡터에 입력받을 때 모두 저장해 놓은뒤

 

- 1번카메라 부터 보면서 1번카메라가 북쪽을 비출 때 -> (깊이 1증가)-> 2번카메라가 어딘가 비출떄.... ->

 

- 종료조건은 모든 카메라가 어딘가를 비추고 있을 때 입니다.

 

 

 

 

 

2. 주의사항 .

 

- 비춘후 다시 맵의 수정한 부분을 0으로 고쳐줬는데 그때 vector를 잘못사용해서 잠시 오류를 겪었습니다.

 

 

 

 

3. 나의코드.

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

int N, M;
int cctvmap[8][8];
struct cctv {
	int x; int y; int num;
};
vector<cctv> carr;
int dx[4] = { -1,0,1,0 }; //북동남서
int dy[4] = { 0,1,0,-1 };

void inputs() {
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> cctvmap[i][j];
			if (cctvmap[i][j] == 6) continue;
			else if (cctvmap[i][j] == 0) continue;
			else { //1,2,3,4,5
				cctv tc; tc.x = i; tc.y = j; tc.num = cctvmap[i][j];
				carr.push_back(tc);
			}
		}
	}
}
int minresult = 64;

void countzero() {
	int resultzero = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (cctvmap[i][j] == 0) resultzero++;
		}
	}
	if (resultzero < minresult) minresult = resultzero;
}

void findzero(int countcctv) {
	if (countcctv == carr.size()) {
		countzero();
		 return;
	}
	for (int i = countcctv; i < carr.size(); i++) {
		if(carr[i].num==1){
			for (int j = 0; j < 4; j++) {
				vector<pair<int, int>> tmpvector;
				int tmpx = carr[i].x; int tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M||cctvmap[tmpx][tmpy]==6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[j]; tmpy += dy[j]; //그 방향으로 계속 전진
				}
				findzero(i + 1);
				for (int k = 0; k < tmpvector.size(); k++) { //다시 맵을 원상태로
					cctvmap[tmpvector[k].first][tmpvector[k].second] = 0;
				}
				tmpvector.clear();
			}
		}
		else if (carr[i].num == 2) {
			for (int j = 0; j < 2; j++) {
				vector<pair<int, int>> tmpvector;
				int tmpx = carr[i].x; int tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[j]; tmpy += dy[j]; //그 방향으로 계속 전진
				}
				tmpx = carr[i].x; tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[j+2]; tmpy += dy[j+2]; //그 방향으로 계속 전진
				}
				findzero(i + 1);
				for (int k = 0; k < tmpvector.size(); k++) { //다시 맵을 원상태로
					cctvmap[tmpvector[k].first][tmpvector[k].second] = 0;
				}
				tmpvector.clear();
				}
			}
		else if(carr[i].num==3){
			for (int j = 0; j < 4; j++) {
				vector<pair<int, int>> tmpvector;
				int tmpx = carr[i].x; int tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[j]; tmpy += dy[j]; //그 방향으로 계속 전진
				}
				tmpx = carr[i].x; tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[(j+1)%4]; tmpy += dy[(j+1)%4]; //그 방향으로 계속 전진

				}
				findzero(i+ 1);
				for (int k = 0; k < tmpvector.size(); k++) { //다시 맵을 원상태로
					cctvmap[tmpvector[k].first][tmpvector[k].second] = 0;
				}
				tmpvector.clear();
			}
		}
		else if(carr[i].num==4){
			for (int j = 0; j < 4; j++) {
				vector<pair<int, int>> tmpvector;
				int tmpx = carr[i].x; int tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[j]; tmpy += dy[j]; //그 방향으로 계속 전진

				}
				 tmpx = carr[i].x;tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[(j+1)%4]; tmpy += dy[(j+1)%4]; //그 방향으로 계속 전진

				}
				 tmpx = carr[i].x; tmpy = carr[i].y;
				while (1) {
					if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
					if (cctvmap[tmpx][tmpy] == 0) {
						cctvmap[tmpx][tmpy] = 7;
						pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
						tmpvector.push_back(tmpp);
					}
					tmpx += dx[(j + 2) % 4]; tmpy += dy[(j + 2) % 4]; //그 방향으로 계속 전진

				}
				findzero(i + 1);
				for (int k = 0; k < tmpvector.size(); k++) { //다시 맵을 원상태로
					cctvmap[tmpvector[k].first][tmpvector[k].second] = 0;
				}
				tmpvector.clear();
			}
		}
		else { //5
		vector<pair<int, int>> tmpvector;
		int tmpx = carr[i].x; int tmpy = carr[i].y;
		while (1) {
			if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
			if (cctvmap[tmpx][tmpy] == 0) {
				cctvmap[tmpx][tmpy] = 7;
				pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
				tmpvector.push_back(tmpp);
			}
			tmpx += dx[0]; tmpy += dy[0]; //그 방향으로 계속 전진

		}
		tmpx = carr[i].x; tmpy = carr[i].y;
		while (1) {
			if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
			if (cctvmap[tmpx][tmpy] == 0) {
				cctvmap[tmpx][tmpy] = 7;
				pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
				tmpvector.push_back(tmpp);
			}
			tmpx += dx[1]; tmpy += dy[1]; //그 방향으로 계속 전진

		}
		tmpx = carr[i].x; tmpy = carr[i].y;
		while (1) {
			if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
			if (cctvmap[tmpx][tmpy] == 0) {
				cctvmap[tmpx][tmpy] = 7;
				pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
				tmpvector.push_back(tmpp);
			}
			tmpx += dx[2]; tmpy += dy[2]; //그 방향으로 계속 전진

		}
		tmpx = carr[i].x;tmpy = carr[i].y;
		while (1) {
			if (tmpx < 0 || tmpx >= N || tmpy < 0 || tmpy >= M || cctvmap[tmpx][tmpy] == 6) { break; } //범위를 넘거나 벽이거나
			if (cctvmap[tmpx][tmpy] == 0) {
				cctvmap[tmpx][tmpy] = 7;
				pair<int, int> tmpp; tmpp.first = tmpx; tmpp.second = tmpy;
				tmpvector.push_back(tmpp);
			}
			tmpx += dx[3]; tmpy += dy[3]; //그 방향으로 계속 전진
		}
		findzero(i + 1);
		for (int k = 0; k < tmpvector.size(); k++) { //다시 맵을 원상태로
			cctvmap[tmpvector[k].first][tmpvector[k].second] = 0;
		}
		tmpvector.clear();
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	findzero(0);
	cout << minresult << "\n";
	return 0;
}

'알고리즘 문제풀이 > DFS와 BFS' 카테고리의 다른 글

백준 6593 [C++]  (0) 2020.12.15
백준 15684 [C++]  (0) 2020.12.09
백준 11404 [C++] ,플로이드 워셜  (0) 2020.10.26
백준 16234[C++]  (0) 2020.10.25
백준 18405 [C++]  (0) 2020.10.25

www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

1. 문제풀이 방법

 

- 테트리스에 너무 익숙한 탓일까요....?

 

- 문제조건에서 대칭을 시켜도 된다는 조건을 빼먹고...이건 뭐 아이디어가 안떠올라서 모든 좌표탐색을 했으나

 

- 대칭을 안넣었으니...당연히 틀릴 수 밖에 없었습니다....

 

- 문제 조건을 다시 파악하고 보니 DFS 깊이 4짜리에 해당하는 모든 좌표가 테트로미노로 표현이 된다는 것을

  알아내었습니다....

 

- 하지만 ㅗ ㅏ ㅜ ㅓ 는 DFS로 표현이 불가능 합니다 (집합느낌으로 보면 테트로미노 > 4짜리 DFS?) 이런느낌?

 

- 그래서 그건 따로 직접 좌표를 설정해 구해주었습니다.

 

 

 

 

2. 주의사항

 

- 문제를 똑바로 파악하자!!!!

 

 

3. 나의코드

#include<iostream>
#include<algorithm>
using namespace std;

int N, M;
int tetro[501][501];
int maxvalue = 0;
int dx[4] = { 0,0,1,-1 };
int dy[4] = { 1,-1,0,0 };
bool visit[501][501];
int depth = 0;
int tmpsum;

void dfs(int x, int y) {
	if (depth == 4) {
		if (tmpsum > maxvalue) maxvalue = tmpsum;
		return;
	}
	for (int i = 0; i < 4; i++) {
		int x2 = x + dx[i];
		int y2 = y + dy[i];
		if (x2 >= 0 && x2 < N &&y2 >= 0 && y2 < M && visit[x2][y2]==false) {
			visit[x2][y2] = true;
			depth++;
			tmpsum += tetro[x2][y2];
			dfs(x2, y2);
			tmpsum -= tetro[x2][y2];
			depth--;
			visit[x2][y2] = false;
		}
	}
}

void cantdfs(int x, int y)
{
	int result = 0;
	if (x - 1 >= 0 && y + 2 < M) {// ㅗ
		result = tetro[x][y] + tetro[x][y + 1] + tetro[x][y + 2] + tetro[x - 1][y + 1];
		if (result > maxvalue) maxvalue = result;
	}
	if (x + 1 < N &&y + 2 < M) { // ㅜ
		result = tetro[x][y] + tetro[x][y + 1] + tetro[x][y + 2] + tetro[x + 1][y + 1];
		if (result > maxvalue) maxvalue = result;
	}
	if (x + 1 < N &&x - 1 >= 0 && y + 1 < M) { // ㅓ
		result = tetro[x][y] + tetro[x][y + 1] + tetro[x - 1][y + 1] + tetro[x + 1][y + 1];
		if (result > maxvalue) maxvalue = result;
	}
	if (x + 2 < N &&y + 1 < M) {
		result = tetro[x][y] + tetro[x + 1][y] + tetro[x + 2][y] + tetro[x + 1][y + 1];
		if (result > maxvalue) maxvalue = result;
	}
}



int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> tetro[i][j];
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			depth = 1;
			tmpsum = tetro[i][j];
			visit[i][j] = true;
			dfs(i, j);
			visit[i][j] = false;
			cantdfs(i, j);
		}
	}
	cout << maxvalue << "\n";

	return 0;
}

'알고리즘 문제풀이 > 완탐' 카테고리의 다른 글

백준 9663 [C++]  (0) 2021.01.13
백준 1107 [C++]  (0) 2020.12.14
백준 17135 [C++]  (0) 2020.10.21
백준 17136 [C++]  (0) 2020.10.20
백준 16637 [C++]  (0) 2020.10.19

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

 

14888번: 연산자 끼워넣기

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다. 

www.acmicpc.net

- 완전탐색 문제입니다..

 

- 저는 bfs를 이용한 완전탐색을 구현하여 모든 경우의 수를 모두 구했습니다.

 

- 구조체 를 선언하여 그 안에 연산자의 수를 count하는 변수들을 각자 모두 들고 있고

 

- 하나씩 사용하여 계산후 사용한 연산자의 수는 하나 줄여주고 다시 큐에 넣습니다.

 

- 이와 같은 방식으로 bfs를 구현하여 모든 경우의 수를 계산한 후 vector 에 넣어

 

- 내림차순 정렬을 통하여 0번째 항과 마지막 항을 출력하였습니다.

 

- 나름 상세하게 주석을 달아놓았습니다.... 도움이 되는 분들이 있었으면 좋겠네요..

 

- 채점현황을 보니 저는 코드가 상당히 긴 편이였습니다.. 한번 다른분들은 어떤방식으로 푸셨는지 저도 한번 알아봐야겠네요 !

<코드>

'알고리즘 문제풀이 > 완탐' 카테고리의 다른 글

백준 1748 : 수 이어 쓰기 1  (0) 2020.03.24
완전탐색(경우의 수) , 순열, 재귀를 통한 구현, 모든 카드 경우의 수  (0) 2020.02.28
백준 14889  (0) 2020.02.24
백준 7568  (0) 2020.02.21
백준 6603  (0) 2020.02.01

+ Recent posts