마법사 상어와 비바라기--c++

고동현·2024년 3월 5일
0

PS

목록 보기
2/51

문제바로가기
이번에 풀어본 문제는 구현문제이다.
난이도: 하
시간:2시간
알고리즘: 구현

문제에서 예시들이 친절하게 설명되어있고, 주석처리를 해두었으니 딱히 어려울 부분이 없는 문제였다.
다만 이 글을 해설을 보기 위해 오신 분들이라면 아마, 구름을 이동시킬때 어떻게 할지 궁금해서 오신분들일 것 같다.
핵심은 dx,dy로 배열을 9개 설정하여서 첫번째인 0을 비워두고, 그다음에 각각의 방향에 맞춰서 -1,0,1을 입력한다.

int dx[9] = { 0,0,-1,-1,-1,0,1,1,1 };
int dy[9] = { 0,-1,-1,0,1,1,1,0,-1 };

그 다음 이문제가 쉽다는 이유가 문제에서 이미 친절하게 어떻게 해야될지 설명해주었다.
마법사 상어는 연습을 위해 1번 행과 N번 행을 연결했고, 1번 열과 N번 열도 연결했다. 즉, N번 행의 아래에는 1번 행이, 1번 행의 위에는 N번 행이 있고, 1번 열의 왼쪽에는 N번 열이, N번 열의 오른쪽에는 1번 열이 있다.

고로 아래의 코드와 같이 N+1일때는 1로 바꾸고, 0일때는 N으로 바꾸면 되는 문제였다.

for (int j = 0; j < s; j++) {
			cx += dx[d];
			cy += dy[d];
			if (cx == 0) cx = N;
			if (cx == N + 1) cx = 1;
			if (cy == 0) cy = N;
			if (cy == N + 1) cy = 1;
}

그 다음부터는 그냥 요구사항대로 따라가면 어려울것이 없는 문제였다.

전체코드

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

int map[51][51] = { 0, };
int N, M;
int dx[9] = { 0,0,-1,-1,-1,0,1,1,1 };
int dy[9] = { 0,-1,-1,0,1,1,1,0,-1 };
queue<pair<int, int>> cloud;
void makemap() {
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			int tmp = 0;
			cin >> tmp;
			map[i][j] = tmp;
		}
	}
}

void movecloud() {
	int d = 0;
	int s = 0;
	cin >> d >> s;
	for (int i = 0; i < cloud.size(); i++) {
		int cx = cloud.front().first;
		int cy = cloud.front().second;
		cloud.pop();
		for (int j = 0; j < s; j++) {
			cx += dx[d];
			cy += dy[d];
			if (cx == 0) cx = N;
			if (cx == N + 1) cx = 1;
			if (cy == 0) cy = N;
			if (cy == N + 1) cy = 1;
		}
		cloud.push({ cx,cy });
	}
}

void plusone() {
	for (int i = 0; i < cloud.size(); i++) {
		int cx = cloud.front().first;
		int cy = cloud.front().second;
		cloud.pop();
		map[cx][cy] += 1;
		cloud.push({ cx,cy });
	}
}

void pluscloud() {

	int tmpmap[51][51] = { 0, };
	for (int x = 0; x < 51; x++) {
		for (int y = 0; y < 51; y++) {
			tmpmap[x][y] = map[x][y];
		}
	}

	for (int i = 0; i < cloud.size(); i++) {

		int cx = cloud.front().first;
		int cy = cloud.front().second;

		//북서방향
		if (cx - 1 >= 1 && cy - 1 >= 1 && map[cx-1][cy-1] > 0) {
			tmpmap[cx][cy] += 1;
		}
		//북동방향
		if (cx - 1 >= 1 && cy + 1 <= N && map[cx-1][cy+1] > 0) {
			tmpmap[cx][cy] += 1;
		}//남서방향
		if (cx +1 <= N && cy - 1 >= 1  && map[cx+1][cy-1] > 0) {
			tmpmap[cx][cy] += 1;
		}//남동방향
		if (cx + 1 <= N && cy + 1 <= N && map[cx+1][cy+1] > 0) {
			tmpmap[cx][cy] += 1;
		}

		cloud.pop();
		cloud.push({ cx,cy });
	}

	for (int x = 0; x < 51; x++) {
		for (int y = 0; y < 51; y++) {
			map[x][y] = tmpmap[x][y];
		}
	}
}

void makenewcloud() {
	bool cloudtrue[51][51] = {};
	int s = cloud.size();
	for (int i = 0; i < s; i++) {
		int cx = cloud.front().first;
		int cy = cloud.front().second;
		cloud.pop();
		cloudtrue[cx][cy] = true;
	}
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (map[i][j] >= 2 && !cloudtrue[i][j]) {
				map[i][j] -= 2;
				cloud.push({ i,j });
			}
		}
	}
}

int main() {
	cin >> N >> M;
	//1번
	makemap();
	//초기구름위치설정
	cloud.push({ N,1 });
	cloud.push({ N,2 });
	cloud.push({ N-1,1 });
	cloud.push({ N-1,2 });

	for (int t = 0; t < M; t++) {
		//2번
		movecloud();
		//3번--구름1만큼추가
		plusone();
		//4번--구름 흡성대법
		pluscloud();
		//5번--구름제외 2이상 구름make,물양-2
		makenewcloud();
	}

	int answer = 0;
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= N; j++) {
			answer += map[i][j];
		}
	}
	cout << answer;
	return 0;
}
profile
항상 Why?[왜썻는지] What?[이를 통해 무엇을 얻었는지 생각하겠습니다.]

0개의 댓글