www.acmicpc.net/problem/11048

 

11048번: 이동하기

준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다. 준규는

www.acmicpc.net

1. 풀이방법

 

- 다이나믹프로그래밍을 이용해서 탑다운 방식으로 해결하였습니다.

 

- 저 같은 경우 1행의 모든 값과 1열의 모든 값들은 가로 또는 세로로 쭉 이동하는 경우밖에 없으므로

 

- 초기화할 때 먼저 쭉 작업을 해서 dp 테이블에 넣어놓은 후 시작하였습니다.

 

 

 

 

 

2. 주의사항

 

- 주의사항은 아니고 풀고난 후에 생각난 건데 얻을 수 있는 최대의 사탕의 수를 구하는 것이므로

 

- 대각선 이동은 빼도 될 것 같습니다.

 

- 사탕을 뺏어간다는 조건이 있지 않은 이상 대각선이 가로->세로, 또는 세로->가로 로 이동하는 것 보다 많은 사탕을 얻을 수는 없기 때문에 사실 확인하지 않아도 될 것입니다.

 

 

 

 

3. 나의코드

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

int N, M;
int candymap[1001][10001];
int dp[1001][1001];

void inputs() {//기본셋팅
	cin >> N >> M;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			cin >> candymap[i][j];
			dp[i][j] = -1; //dp테이블은 -1로 초기화
		}
	}
	dp[1][1] = candymap[1][1];
	for (int i = 2; i <= N; i++) {
		dp[i][1] = dp[i - 1][1]+candymap[i][1];
	}
	for (int j = 2; j <= N; j++) {
		dp[1][j] = dp[1][j-1]+candymap[1][j];
	}
}
int maxthree(int num1, int num2, int num3) {
	int tmp = max(num1, num2);
	tmp = max(tmp, num3);
	return tmp;
}
int getdp(int x, int y) {
	if (dp[x][y] != -1) return dp[x][y];
	else {
		dp[x][y] = maxthree(getdp(x - 1, y), getdp(x, y - 1), getdp(x - 1, y - 1))+candymap[x][y];
		return dp[x][y];
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	cout << getdp(N,M) << "\n";
	return 0;
}

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

백준 1965 [C++]  (0) 2021.02.03
백준 1463 [C++] - 메모리초과  (0) 2020.12.15
백준 11726 [C++]  (0) 2020.12.14
백준 7570 [C++]  (0) 2020.12.02
백준 12865 [C++]  (0) 2020.11.29

www.acmicpc.net/problem/11726

 

11726번: 2×n 타일링

2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오. 아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.

www.acmicpc.net

1. 풀이방법

- 이 문제를 접할 때 점화식을 생각해내는 게 생각보다 어려웠습니다.

 

- 물론 이런 류의 문제는 알고나면 매우 간단하기는 하지만......!

 

- 결국 점화식은 dp[n]=dp[n-1] + dp[n-2] 입니다 

 

- 그림을 보시면 이해가 쉬우실 듯 합니다.

 

 

2. 주의사항

 

- 값을 저장할 테이블을 구성해서 메모이제이션을 활용하여 시간을 단축시켜주었습니다.

 

- 탑다운 방식으로 재귀함수만을 이용하여 연산하는 경우 중복되는 연산을 너무나 많이 하기때문에

 

- TIME LIMIT을 만나실 수 있습니다.

 

- 저장되어있는값이 있으면 바로 리턴해서 가져다 쓰고 새로운 값이면 테이블에 저장을 한 후 리턴해서

 

- 다음부터는 그 값이 필요할 때 테이블에서 바로 가져다 쓸 수 있도록 하면 됩니다.

 

 

 

 

 

3. 나의코드

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

int  n;
int dp[1001];

int getdpvalue(int num) {
	if (dp[num] == 0) { 
		dp[num] = (getdpvalue(num - 1) % 10007 + getdpvalue(num - 2) % 10007);
		return dp[num] % 10007;
	}
	else return dp[num]%10007;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n;
	dp[1] = 1; dp[2] = 2; dp[3] = 3; // 3을 초기화안해줘도 되긴하다
	                                 // (하지만 경우의수 그림 그려놨으니까..아까워서)
	cout<<getdpvalue(n)<<"\n";

	return 0;
}

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

백준 1463 [C++] - 메모리초과  (0) 2020.12.15
백준 11048 [C++]  (0) 2020.12.14
백준 7570 [C++]  (0) 2020.12.02
백준 12865 [C++]  (0) 2020.11.29
백준 1932  (0) 2020.03.02

www.acmicpc.net/problem/15684

 

15684번: 사다리 조작

사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선

www.acmicpc.net

1. 풀이방법

 

- 일단 사다리에 대한 표현을 어떻게 할까 고민하다가 저는 char 2차원배열을 선언해서 'R' 또는 'L' 을 넣어서

 

- 오른쪽으로 가는 경우, 왼쪽으로 가는 경우를 구현했습니다.

 

- 그렇게 선언한 후 어떤식으로 찾을 까 고민을 하다가(약간 막막)

 

- 추가하는 최대 line의 수가 3보다 많아지면 그냥 -1을 출력하라는 조건을 보고 아 dfs를 돌리는데 깊이가 3보다 커지

 

- 면 return을 하는 식으로 구현해야겠다 ( 깊이 3정도니까 전체를 다 보아도 시간초과가 안나겠지???) 라는 생각...!!

 

 

 

 

2. 주의사항

 

- 저 같은 경우 아주 초보적인 실수를 했는데 코드에도 주석으로 달아 놓겠지만.....

 

- 2차원배열로 dfs를 돌때!!

 

- for(int i=x;i<....){

        for(int j=y;j<....{

                     function (i,j+1,cnt+1);       

                  }

            }

 

-이런식으로 했다가 헤맸습니다... 이러면 안쪽반복문을 i가 갱신될때는 0부터 돌아야하는데 계속 y부터만 돌게 됩니다

 

- 저는 안쪽반복문은 그냥 계속 0부터 돌게끔 수정했습니다....(그래서인지 다른 사람들보다는 시간이 약간 길게 걸린 듯)

 

 

 

 

 

3. 나의코드

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

int N, M, H;
char sadari[31][11];
int a, b;
int minresult=4; //3 이하; 그 이상은 -1;
bool suc = false;

void inputs() {
	cin >> N >> M >> H;
	for (int i = 0; i < M; i++) {
		cin >> a >> b;
		sadari[a][b] = 'R';
		sadari[a][b + 1] = 'L';
	}
}
bool checkingright() {
	for (int i = 1; i <= N; i++) {
		int resultcount = i;
		for (int j = 1; j <= H; j++){
			if (sadari[j][i] == 'R') i++;
			else if(sadari[j][i]=='L') i--;
			else continue;
		}
		if (resultcount != i) return false;
		i = resultcount;
	}
	return true;
}
void findline(int x,int cnt) {
	if (cnt > 3) { return; } 
	if (checkingright() == true) {
		if (minresult > cnt) { minresult = cnt; }
		suc = true;
		return;
	}; //성공
	for (int a = x; a < N; a++) {
		for (int b = 1; b <= H; b++) {// for(int b=y;b<=H;b++) xxxxxxxxxx!
			if (sadari[b][a] != 0 || sadari[b][a+1]!=0) continue; //이미 연결되어있음
			else {
				sadari[b][a] = 'R';
				sadari[b][a + 1] = 'L';

				findline(a,cnt + 1);  //findline(a,b+1,cnt+1) xxxxxxxx!

				sadari[b][a + 1] = 0;
				sadari[b][a] = 0;
			}
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	findline(1,0);
	if (suc == false) { cout << -1 << "\n"; }
	else cout << minresult << "\n";
	return 0;
}

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

백준 16397 [C++]  (0) 2020.12.18
백준 6593 [C++]  (0) 2020.12.15
백준 15683 [C++]  (0) 2020.12.08
백준 11404 [C++] ,플로이드 워셜  (0) 2020.10.26
백준 16234[C++]  (0) 2020.10.25

www.acmicpc.net/problem/15685

 

15685번: 드래곤 커브

첫째 줄에 드래곤 커브의 개수 N(1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 드래곤 커브의 정보가 주어진다. 드래곤 커브의 정보는 네 정수 x, y, d, g로 이루어져 있다. x와 y는 드래곤 커

www.acmicpc.net

1. 풀이방법

 

- 처음에 드래곤커브 그림만 보아서는 무슨 규칙인지....그려봐도 무슨규칙인지......반복문으로 표현이 가능한지....

 

- 전혀 풀이방법이 생각이 안나다가.... 문제를 계속 보면 문제에서 직접 방향 0,1,2,3에 대한 정보가 나오고 개인적으로는

 

- 강조하는 느낌....?이 들었습니다.

 

- 드래곤커브를 세대별로 써보면 다음과 같습니다. (방향 0으로 시작할 때)

   - 0세대 :0

   - 1세대 :01

   - 2세대 :0121

   - 3세대 :01212321

   - 4세대 :0121232123032321

 

- 잘보시면 규칙이 있습니다 이전세대에서 다음세대로 넘어갈때 이전세대의 길이만큼 늘어나는데

 

- 이전세대의 역순 INDEX (뒤쪽부터) (curve[reverindex]+1) % 4 가 다음세대에 차례로 추가됩니다.

   (저도 찾지 못해서 힌트를 얻어 알아냈습니다.....)

 

- 이것만 알게되면 방향순서를 차례로 구해서 visit에 방문체크만 해주시면 됩니다.....!

 

 

 

 

2. 주의사항

 

- 좌표계가 제가 평소 익숙하게 (다른 문제에도 자주) 다루는 좌표계랑 반대입니다. 주의 !

 

 

 

 

3. 나의코드

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

int N;
int x, y, d, g;
bool visit[102][102];
int resultcount;
int dy[4] = { 0,-1,0,1 };// 동북서남(0,1,2,3)
int dx[4] = { 1,0,-1,0 };
int dragon[1024];
void setvisit() {
	for (int i = 0; i < 101; i++) {
		for (int j = 0; j < 101; j++) {
			visit[i][j] = false;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	setvisit();
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> x >> y >> d >> g;
		dragon[0] = d;
		visit[y][x] = true;
		//드래곤커브 방향 구하기
		for (int j = 1; j <= g; j++) { //세대별로
			int reverseindex = pow(2, j - 1) - 1;
			for (int k = pow(2, j - 1); k < pow(2, j); k++) {
				dragon[k] = (dragon[reverseindex] + 1) % 4;
				reverseindex--;
			}
		}
		for (int j = 0; j < pow(2, g); j++) {//방문처리
				x += dx[dragon[j]]; y += dy[dragon[j]];
				visit[y][x] = true;
		}
	}
	for (int i = 0; i < 101; i++) {
		for (int j = 0; j < 101; j++) {
			if (visit[i][j] == true && visit[i + 1][j] == true && visit[i][j + 1] == true && visit[i + 1][j + 1] == true)
				resultcount++;
		}
	}
	cout << resultcount << "\n";
	return 0;
}

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

백준 20055 [C++]  (0) 2020.12.23
백준 13458 [C++]  (0) 2020.12.15
백준 17144 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08

www.acmicpc.net/problem/17144

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net

1. 풀이방법

 

- 온전한 구현문제 인 것 같습니다..

 

- 문제의 조건을 잘 파악하고 문제에서 원하는 대로 구현을 해주면 됩니다.

 

 

 

 

2. 주의사항

 

- 이 문제에서의 먼지가 퍼지는 것과 같이 가정상 한번에 쫙 퍼지는 것은 한좌표의 결과가 다른 좌표의 입력으로 들어가

   는 것을 조심해야 합니다.

 

- 저는 그래서 이전 단계의 좌표계 (roominfo)를 (copyroom)으로 복사해서 연산을 할 때는 copyroom으로 계산하고 결과를 roominfo에 넣었습니다.

 

 

 

3. 나의코드

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

int R, C, T;
int roominfo[51][51];
int copyroom[51][51];
int dx[4] = { 0,0,1,-1 }; //동서남북
int dy[4] = { 1,-1,0,0 };
int reverseclockx[4] = { 0,-1,0,1 }; //반시계
int reverseclocky[4] = { 1,0,-1,0 };
int clockx[4] = { 0,1,0,-1 }; //시계
int clocky[4] = { 1,0,-1,0 };
int dust;
vector<pair<int, int>> airfresh;

void inputs() {
	cin >> R >> C >> T;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			cin >> roominfo[i][j];
			if (roominfo[i][j] == -1) {
				pair<int, int> tmpp; tmpp.first = i; tmpp.second = j;
				airfresh.push_back(tmpp);
			}
		}
	}
}

void dustmove() { //먼지이동
	for (int a = 0; a < R; a++) {
		for (int b = 0; b < C; b++) {
			if (roominfo[a][b] == -1) continue;
			int movedust = 0;
			for (int i = 0; i < 4; i++) {
				if (a + dx[i] < 0 || a + dx[i] >= R || b + dy[i] < 0 || b + dy[i] >= C) continue;
				if (roominfo[a + dx[i]][b + dy[i]] == -1) continue;
				roominfo[a + dx[i]][b+dy[i]] += copyroom[a][b] / 5;
				movedust++;
			}
			roominfo[a][b] -= (copyroom[a][b] / 5)*movedust;
		}
	}

}

void airclean() { //순환(공기청정)
	int dir = 0;
	int tmp,tmp2;
	int nextX = airfresh[0].first + reverseclockx[dir]; int nextY = airfresh[0].second + reverseclocky[dir];
	tmp = roominfo[nextX][nextY];
	roominfo[nextX][nextY] = 0;
	while (1) { //위쪽(반시계)
		if (nextX + reverseclockx[dir] == airfresh[0].first &&nextY + reverseclocky[dir] == airfresh[0].second) break; //공기 청정기를 만남
		if (nextX + reverseclockx[dir] == R || nextX + reverseclockx[dir] == -1 || nextY + reverseclocky[dir] == -1 || nextY + reverseclocky[dir] == C) { dir++; continue; }
		nextX += reverseclockx[dir]; nextY += reverseclocky[dir];
		tmp2 = roominfo[nextX][nextY];
		roominfo[nextX][nextY] = tmp;
		tmp = tmp2;
	}
	             //아래쪽(시계)
	dir = 0;
	nextX = airfresh[1].first + clockx[dir];  nextY = airfresh[1].second + clocky[dir];
	tmp = roominfo[nextX][nextY];
	roominfo[nextX][nextY] = 0;
	while (1) {
		if (nextX + clockx[dir] == airfresh[1].first &&nextY + clocky[dir] == airfresh[1].second) break;//공기 청정기를 만남
		if (nextX + clockx[dir] == R || nextX + clockx[dir] == -1 || nextY + clocky[dir] == -1 || nextY + clocky[dir] == C) { dir++; continue; }
		nextX += clockx[dir]; nextY += clocky[dir];
		tmp2 = roominfo[nextX][nextY];
		roominfo[nextX][nextY] = tmp;
		tmp = tmp2;
	}
}
void getdust() {
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			if (roominfo[i][j] > 0) dust += roominfo[i][j];
			}
		}
}
void copymap() {
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			copyroom[i][j] = roominfo[i][j];
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	inputs();
	for (int i = 0; i < T; i++) {
		copymap();
		dustmove();
		airclean();
	}
	getdust();
	cout << dust << "\n";
	return 0;
}

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

백준 13458 [C++]  (0) 2020.12.15
백준 15685 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06

www.acmicpc.net/problem/14499

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도

www.acmicpc.net

1. 풀이방법

 

- 문제의 조건을 잘 파악합니다 (처음 읽으면 이게 뭔말인가......싶습니다.)

 

- 주사위에서 잠깐 멈칫했지만 주사위 전개도를 가지고 동/서/북/남 으로 돌렸을 때의 전개도도 그려보고

 

- 이동방향에 따라 값을 수정해주면 됩니다

 

- 저같은 경우 윗면은 항상 dice[1], 아랫면은 항상 dice[6]

 

 

 

 

2. 주의사항

 

- 문제를 읽고 이해하기

 

 

 

3. 나의코드

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


int N, M, K;
int x, y;
int jido[21][21];
int dice[7]; //주사위 (1~6면) //윗면이 무조건 dice[1] ,아랫면이 dice[6]
int dx[5] = { 0,0,0,-1,1 };
int dy[5] = { 0,1,-1,0,0 };

void movedice(int c) {
	if(c==1){ //동
		int tmpdice[7];
		tmpdice[6] = dice[3]; tmpdice[3] = dice[1];
		tmpdice[4] = dice[6]; tmpdice[1] = dice[4];
		tmpdice[5] = dice[5]; tmpdice[2] = dice[2];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if(c==2){
		int tmpdice[7];
		tmpdice[6] = dice[4]; tmpdice[3] = dice[6];
		tmpdice[4] = dice[1]; tmpdice[1] = dice[3];
		tmpdice[5] = dice[5]; tmpdice[2] = dice[2];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if (c == 3){
		int tmpdice[7];
		tmpdice[6] = dice[2]; tmpdice[2] = dice[1];
		tmpdice[5] = dice[6]; tmpdice[1] = dice[5];
		tmpdice[3] = dice[3]; tmpdice[4] = dice[4];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if (c == 4) {
		int tmpdice[7];
		tmpdice[6] = dice[5]; tmpdice[2] = dice[6];
		tmpdice[5] = dice[1]; tmpdice[1] = dice[2];
		tmpdice[3] = dice[3]; tmpdice[4] = dice[4];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N >> M >>x>>y>>K;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> jido[i][j];
		}
	}
	int command;
	for (int i = 0; i < K; i++) {
		cin >> command;
		if (x + dx[command] < 0 || x + dx[command] >= N || y + dy[command] < 0 || y + dy[command] >= M) continue;
		movedice(command);
		if (jido[x + dx[command]][y + dy[command]] == 0) {
			jido[x + dx[command]][y + dy[command]] = dice[6];
		}
		else {
			dice[6] = jido[x + dx[command]][y + dy[command]];
			jido[x + dx[command]][y + dy[command]] = 0;
		}
		x += dx[command]; y += dy[command];
		cout << dice[1] << "\n";
	}
	return 0;
}

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

백준 15685 [C++]  (0) 2020.12.08
백준 17144 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06
백준 2840 [C++]  (0) 2020.12.06

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/14503

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

1. 풀이방법.

- 문제의 조건대로 차례로 구현을 해주면 되며,

- 문제에서 첫행,첫열,끝행,끝열은 모두 벽이다 라는 조건도 맞추어 주었으므로 경계의 범위도 신경쓰지 않아도 되서

- 매우 편한 문제였습니다.

- 저 같은 경우 3,4 번의 종료조건을 먼저 체크해주고 그것의 결과에따라 변동을 주는 쪽으로 코드를 짰습니다.

 

 

 

2. 주의사항

- 딱히 없습니다. (저는 청소할 구역은 0, 벽은 1, 청소한 구역은 2 로 설정하였습니다.)

 

 

 

3.나의코드

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

int dx[4] = { -1,0,1,0 }; //북동남서
int dy[4] = { 0,1,0,-1 }; //0,1,2,3
int N, M;
int rx, ry, rd;
int robomap[51][51]; //빈칸은 0, 벽은 1
int cleancount;

void inputs() {
	cin >> N >> M;
	cin >> rx >> ry >> rd;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> robomap[i][j];
		}
	}
}

void cleanroom() {
	while (1) {
		if (robomap[rx][ry] == 0) {
			robomap[rx][ry] = 2; //청소
			cleancount++;
		}
		bool lastcheck = false;
		for (int i = 0; i < 4; i++) {//종료조건 검사
			if (robomap[rx + dx[i]][ry + dy[i]] == 0) { lastcheck = true; break; }
		}
		if (lastcheck == false) {
			if (robomap[rx + dx[(rd + 2) % 4]][ry + dy[(rd + 2) % 4]] == 1) { 
				cout << cleancount << "\n"; break;
			}
			else {
				rx += dx[(rd + 2) % 4]; ry += dy[(rd + 2) % 4];
			}
		}
		else if (lastcheck == true) {
			while (1) {
				if (robomap[rx + dx[(rd + 3) % 4]][ry + dy[(rd + 3) % 4]] == 0) {
					rd = (rd + 3) % 4;
					rx += dx[rd]; ry += dy[rd];
					break;
				}
				else {
					rd = (rd + 3) % 4;
				}
			}
		}
	}
}

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

	return 0;
}

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

백준 17144 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06
백준 2840 [C++]  (0) 2020.12.06
백준 2033 C++  (0) 2020.11.25

+ Recent posts