반응형
포인트
- 정해진 배열을 잘 돌릴 수 있는가?
- 배열을 밀고 땡긴다라고 생각하면 헷갈릴 수 있다. 값을 복사한다고 생각하면 된다. 그리고 시작지점에 그 다음 번째 값을 복사해주자
🧶문서는 항상 수정 될 수 있습니다. 비판은 환영합니다.
c++/cpp
#include<iostream>
#include<vector>
#define endl "\n"
#define MAX 50 + 1
#define K_MAX 6
using namespace std;
struct info {
int R, C, S;
};
int n, m, k, answer;
int map[MAX][MAX];
int cmap[MAX][MAX];
bool sel[K_MAX];
vector<info> vc;
vector<int> turn;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int change_Direction(int cur) {
if (cur == 0) return 3;
if (cur == 1) return 2;
if (cur == 2) return 0;
if (cur == 3) return 1;
}
void simulation(info T) {
/*=======================================================================*/
/*실제로 배열을 돌려보는 함수.
1. while문을 통해서 각 라인별이 아닌, 한 번에 처리하는 식으로 구현.
2. 돌려야 할 사각형의 범위 밖으로 나가는 경우 방향을 바꿔주는 식으로 구현. */
/*=======================================================================*/
int sx = T.R - T.S;
int sy = T.C - T.S;
int ex = T.R + T.S;
int ey = T.C + T.S;
int count = (ex - sx) / 2; // 몇 개의 사각형을 돌려줘야 하는지
for (int i = 0; i < count; i++) // 돌려야 할 사각형의 갯수만큼 반복
{
int x = sx; // x = 시작 X좌표
int y = sy; // y = 시작 y좌표
int Temp = cmap[x][y]; // 가장 첫 시작점을 Temp에 임시적으로 저장
int d = 2; // 0 = 동, 1 = 서, 2 = 남, 3 = 북. 첫 방향은 남쪽 !
/* 첫 방향을 남쪽으로 잡은 이유
- 시계방향으로 배열이 회전되는 것이기 때문에, 이는 어떻게 보면
자기 자신을 기준으로 반 시계 방향에 있는 값이 자기 자신의 자리에 위치하게 된다.
즉, 시작점을 기준으로 왼쪽 세로변, 하단 가로변, 우측 세로변, 상단 가로변 순서로
움직이면서 값을 설정해 주었다. */
while (1) {
int nx = x + dx[d];
int ny = y + dy[d];
// (nx, ny) = 위에서 말했듯이, 현재 자기자신을 기준으로 한 칸 왼쪽(반시계방향) 에 있는 좌표
if (nx == sx && ny == sy) // 다시 처음 위치로 돌아오게 된다면
{
cmap[x][y] = Temp; // 위에서 저장해둔 임시 저장 값으로 값을 설정 후 종료.
break;
}
if (sx <= nx && nx <= ex - i && sy <= ny && ny <= ey - i) // 현재 사각형의 범위 내에 있는 좌표라면
{
cmap[x][y] = cmap[nx][ny]; // 자기자신의 자리에 반 시계방향에 있는 좌표를 넣어준다.
x = nx; // x값 재설정
y = ny; // y값 재설정
}
else {
/* 그렇게, 방향을 따라가다 보면 정해진 사각형의 범위를 벗어나는 경우가 존재함.
그럴 때는 방향을 바꿔준다.
남쪽 -> 동쪽 -> 북쪽 -> 서쪽 순으로 ! */
d = change_Direction(d);
}
}
sx++;
sy++;
/* 그 다음 사각형으로 가기 위한 sx, Sy값 설정.
만약, 돌려야 할 사각형의 갯수가 2개이고, 가장 바깥쪽 사각형의 시작점이 (1, 1)이엿다면
그 다음으로 돌려야 할 사각형의 시작점은 (2, 2)가 될 것이다.
즉, sx++ ,sy++ */
}
}
int calc() {
int value = 987654321;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 1; j <= m; j++) {
sum += cmap[i][j];
}
value = min(value, sum);
}
return value;
}
void go(int cnt) {
if (cnt == k) {
memcpy(cmap, map, sizeof (map));
for (int i = 0; i < turn.size(); i++) {
int order = turn[i];
simulation(vc[order]);
}
answer = min(answer, calc());
return;
}
/* 배열을 돌리는 순서를 정하기 위한 (순열 생성을 위한) 반복문. */
for (int i = 0; i < vc.size(); i++) {
if (sel[i] == true) continue;
sel[i] = true;
turn.push_back(i);
go(cnt + 1);
turn.pop_back();
sel[i] = false;
}
}
int main(void) {
answer = 987654321;
cin >> n >> m >> k;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}
for (int i = 0; i < k; i++) {
int r, c, s;
cin >> r >> c >> s;
vc.push_back({r, c, s});
}
go(0);
cout << answer << endl;
return 0;
}
python
import sys
from itertools import permutations
from copy import deepcopy
def rotate(operation, copy_data):
global answer
for case in operation:
row, column, s = case
row -= 1
column -= 1
print(row, column, s)
for k in range(s, 0, -1): # 횐전 개수
top_right = copy_data[row - k][column + k]
# 오른쪽 위치를 저장한다.
bottom_left = copy_data[row + k][column - k]
# 왼쪽 아래 위치를 저장한다.
bottom_right = copy_data[row + k][column + k]
# 오른쪽 아래 위치를 저장한다.
for y in range(column + k, column - k, -1): # 위 행을 민다
copy_data[row - k][y] = copy_data[row - k][y - 1]
for x in range(row + k, row - k, -1): # 오른쪽 열을 민다
copy_data[x][column + k] = copy_data[x - 1][column + k]
for y in range(column - k, column + k): # 아래쪽 행을 떙긴다
copy_data[row + k][y] = copy_data[row + k][y + 1]
for x in range(row - k, row + k): # 왼쪽 열을 땡긴다
copy_data[x][column - k] = copy_data[x + 1][column - k]
# 이렇게 땡기면 처음 시작 지점을 제외하고
# 빈 공간을 채워준다.
copy_data[row - k + 1][column + k] = top_right
copy_data[row + k][column + k - 1] = bottom_right
copy_data[row + k - 1][column - k] = bottom_left
for row in copy_data:
answer = min(answer, sum(row))
n, m, k = map(int, sys.stdin.readline().split())
data = [list(map(int, input().split())) for _ in range(n)]
rotates = [list(map(int, input().split())) for _ in range(k)]
answer = 987654321
for operation in permutations(rotates, k):
rotate(operation, deepcopy(data))
print(answer)
반응형
'알고리즘' 카테고리의 다른 글
[알고리즘] 테트로미노 (0) | 2020.10.14 |
---|---|
[알고리즘] 괄호 추가하기 (0) | 2020.10.14 |
[알고리즘] c++ cpp 구슬탈출 시리즈 (구슬탈출1) (0) | 2020.10.09 |
[알고리즘] 구슬 탈출 시리즈 (구슬 탈출 2) (0) | 2020.10.09 |
[알고리즘] c++ cpp 구슬탈출 시리즈 (구슬탈출4) (0) | 2020.10.09 |
댓글