프로그래머스에 비하면 삼성 코테 문제는 굉장히 양반인 것 같다.
딱히 어려운 구현은 없고, 주어진데로 잘 구현하면 된다.
주의할 점이라면 원판에서 같은 숫자 쌍이 없을 경우 평균을 구하고, 평균보다 큰 원판의 숫자는 -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;
}