-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path17406_배열 돌리기 4.cpp
147 lines (121 loc) · 2.65 KB
/
17406_배열 돌리기 4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <vector>
#include <cstring>
#define INF 987654321
using namespace std;
struct Info {
int sx, sy, ex, ey;
Info(int r, int c, int s) : sx(r - s), sy(c - s), ex(r + s), ey(c + s) { }
};
int n, m, k;
int a[51][51];
int na[51][51];
bool visited[6];
vector<Info> info;
int dx[] = { 0, 1, 0, -1 };
int dy[] = { 1, 0, -1, 0 };
bool isWall(int x, int y, Info info)
{
return x < info.sx || x > info.ex || y < info.sy || y > info.ey;
}
void rotate(Info info)
{
int b[51][51]; // 연산을 수행한 결과를 저장할 배열
memset(b, 0, sizeof(b));
int dir = 0;
int x, y; // 현재 위치
// 다음 위치
int nx = info.sx;
int ny = info.sy;
int r = info.ex - info.sx + 1;
int c = info.ey - info.sy + 1;
while (1) {
int cnt = (r + c - 2) * 2; // 이동시킬 칸 개수
if (cnt < 1) { // 더 이상 이동시킬 게 없으면 마지막 원소를 b 배열에 저장하고 종료
b[nx][ny] = na[nx][ny];
break;
}
for (int i = 0; i < cnt; i++) {
x = nx;
y = ny;
nx = x + dx[dir];
ny = y + dy[dir];
// 벽이거나 이미 들렀던 곳이면 방향을 바꾼다
if (isWall(nx, ny, info) || b[nx][ny] != 0) {
dir = (dir + 1) % 4;
nx = x + dx[dir];
ny = y + dy[dir];
}
// 현재 칸의 수를 다음 칸에 저장
b[nx][ny] = na[x][y];
}
r -= 2; c -= 2;
nx += 1; ny += 1;
}
// 회전 결과를 na 배열에 저장한다
for (int i = info.sx; i <= info.ex; i++) {
for (int j = info.sy; j <= info.ey; j++) {
na[i][j] = b[i][j];
}
}
}
// 배열의 값 구하기 (각 행에 있는 모든 수의 합 중 최솟값)
int calc()
{
int result = INF;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 1; j <= m; j++) {
sum += na[i][j];
}
result = min(result, sum);
}
return result;
}
int go(vector<int> seq)
{
if (seq.size() == info.size()) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
na[i][j] = a[i][j];
}
}
// 회전 연산 수행
for (int i = 0; i < seq.size(); i++) {
rotate(info[seq[i]]);
}
return calc();
}
int ret = INF;
for (int next = 0; next < info.size(); next++) {
if (!visited[next]) {
// 다음 연산 선택
seq.push_back(next);
visited[next] = true;
ret = min(ret, go(seq));
// 원래대로
seq.pop_back();
visited[next] = false;
}
}
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
for (int i = 0; i < k; i++) {
int r, c, s;
cin >> r >> c >> s;
info.push_back(Info(r, c, s));
}
cout << go(vector<int>());
return 0;
}