백준 - 원판 돌리기 (17822번)

well-life-gm·2021년 12월 1일
0

백준 삼성

목록 보기
19/23

백준 - 원판 돌리기 (17822번)

프로그래머스에 비하면 삼성 코테 문제는 굉장히 양반인 것 같다.
딱히 어려운 구현은 없고, 주어진데로 잘 구현하면 된다.
주의할 점이라면 원판에서 같은 숫자 쌍이 없을 경우 평균을 구하고, 평균보다 큰 원판의 숫자는 -1을 작은 숫자는 +1을 해줘야하는데, 이 연산이 초과 미만 연산이라는 것이다.

코드는 아래와 같다.

#include <cstdio>
#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;

int n, m, t;

int onepan[64][64];
int spin_info[64][3];
int remove_mark[64][64];

void print_map(const char *s)
{
	printf("%s\n", s);
	for(int i = 0; i < n; i++) {
		printf("onepan[%d] : ", i + 1);
		for (int j = 0; j < m; j++) {
			printf("%d ", onepan[i][j]);
		}
		printf("\n");
	}
}
void move(int dir, int len, int idx)
{
	int tmp[64];
	for (int i = 0; i < m; i++)
		tmp[i] = onepan[idx][i];
	
	if (dir == 0) {
		for (int i = m - 1; i >= 0; i--) {
			int loc = i - len < 0 ? i - len + m : i - len;
			onepan[idx][i] = tmp[loc];
		}
	}
	else {
		// 반시계
		for (int i = 0; i < m; i++) {
			int loc = i + len > m - 1 ? i + len - m : i + len;
			onepan[idx][i] = tmp[loc];
		}
	}
}
void remove_onepan()
{
	for (int i = 0; i < n; i++) 
		for (int j = 0; j < m; j++) 
			remove_mark[i][j] = 0;
	
	bool is_same_exist = false;
	// 같은 원판에서 같은 것 있는지 체크.
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (onepan[i][j] == -1)
				continue;
			if (j == 0) {
				if (onepan[i][0] == onepan[i][m - 1]) {
					remove_mark[i][0] = -1;
					remove_mark[i][m - 1] = -1;
					is_same_exist = true;
				}
				if (onepan[i][0] == onepan[i][1]) {
					remove_mark[i][0] = -1;
					remove_mark[i][1] = -1;
					is_same_exist = true;
				}
			}
			else if (j == m - 1) {
				if (onepan[i][m - 1] == onepan[i][0]) {
					remove_mark[i][m - 1] = -1;
					remove_mark[i][0] = -1;
					is_same_exist = true;
				}
				if (onepan[i][m - 1] == onepan[i][m - 2]) {
					remove_mark[i][m - 1] = -1;
					remove_mark[i][m - 2] = -1;
					is_same_exist = true;
				}
			}
			else {
				if (onepan[i][j] == onepan[i][j - 1]) {
					remove_mark[i][j] = -1;
					remove_mark[i][j - 1] = -1;
					is_same_exist = true;
				}
				if (onepan[i][j] == onepan[i][j + 1]) {
					remove_mark[i][j] = -1;
					remove_mark[i][j + 1] = -1;
					is_same_exist = true;
				}
			}
		}
	}
	// 원판 사이에서 같은 것이 있는지 체크
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (onepan[j][i] == -1)
				continue;
			if (j == 0) {
				if (onepan[0][i] == onepan[1][i]) {
					remove_mark[0][i] = -1;
					remove_mark[1][i] = -1;
					is_same_exist = true;
				}
			}
			else if (j == n - 1) {
				if (onepan[n - 1][i] == onepan[n - 2][i]) {
					remove_mark[n - 1][i] = -1;
					remove_mark[n - 2][i] = -1;
					is_same_exist = true;
				}
			}
			else {
				if (onepan[j][i] == onepan[j - 1][i]) {
					remove_mark[j][i] = -1;
					remove_mark[j - 1][i] = -1;
					is_same_exist = true;
				}
				if (onepan[j][i] == onepan[j + 1][i]) {
					remove_mark[j][i] = -1;
					remove_mark[j + 1][i] = -1;
					is_same_exist = true;
				}
			}
		}
	}

	if (is_same_exist) {
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				onepan[i][j] = remove_mark[i][j] ? -1 : onepan[i][j];
	}
	else {
		int total_cnt = 0;
		int total_sum = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (onepan[i][j] == -1)
					continue;
				total_cnt++;
				total_sum += onepan[i][j];
			}
		double avg = (double)total_sum / total_cnt;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (onepan[i][j] == -1)
					continue;
				if ((double)onepan[i][j] > avg)
					onepan[i][j]--;
				else if((double)onepan[i][j] < avg)
					onepan[i][j]++;
			}
	}
}
int get_answer()
{
	int total = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (onepan[i][j] == -1)
				continue;
			total += onepan[i][j];
		}
	}

	return total;
}
int main(void)
{
	cin >> n >> m >> t;
	for (int i = 0; i < n; i++) 
		for (int j = 0; j < m; j++) 
			cin >> onepan[i][j];
		
	for (int i = 0; i < t; i++) 
		for (int j = 0; j < 3; j++)
			cin >> spin_info[i][j];

	for (int i = 0; i < t; i++) {
		for (int j = 0; j < n; j++) 
			if ((j + 1) % spin_info[i][0] == 0) 
				move(spin_info[i][1], spin_info[i][2], j);
		remove_onepan();
	}

	int answer = get_answer();

	cout << answer << "\n";

	return 0;
}
profile
내가 보려고 만든 블로그

0개의 댓글

관련 채용 정보