https://www.acmicpc.net/problem/17406
문제
크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의 값은 4이다.
1 2 3
2 1 1
4 5 6
배열은 회전 연산을 수행할 수 있다. 회전 연산은 세 정수 (r, c, s)로 이루어져 있고, 가장 왼쪽 윗 칸이 (r-s, c-s), 가장 오른쪽 아랫 칸이 (r+s, c+s)인 정사각형을 시계 방향으로 한 칸씩 돌린다는 의미이다. 배열의 칸 (r, c)는 r행 c열을 의미한다.
배열 A에 (3, 4, 2), (4, 2, 1) 순서로 연산을 수행하면 배열 A의 값은 12, (4, 2, 1), (3, 4, 2) 순서로 연산을 수행하면 15 이다.
배열 A와 사용 가능한 회전 연산이 주어졌을 때, 배열 A의 값의 최솟값을 구해보자. 회전 연산은 모두 한 번씩 사용해야 하며, 순서는 임의로 정해도 된다.
입력
첫째 줄에 배열 A의 크기 N, M, 회전 연산의 개수 K가 주어진다.
둘째 줄부터 N개의 줄에 배열 A에 들어있는 수 A[i][j]가 주어지고, 다음 K개의 줄에 회전 연산의 정보 r, c, s가 주어진다.
출력
배열 A의 값의 최솟값을 출력한다.
제한
-
3 ≤ N, M ≤ 50
-
1 ≤ K ≤ 6
-
1 ≤ A[i][j] ≤ 100
-
1 ≤ s
-
1 ≤ r-s < r < r+s ≤ N
-
1 ≤ c-s < c < c+s ≤ M
예제 입력
5 6 2
1 2 3 2 5
6 3 8 7 2
1 3 8 2 3
1 4 5 3 4
5 1 1 1 9
3 2 1 4 3
3 4 2
4 2 1
예제 출력
12
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int map[51][51];
int copyMap[51][51];
int chk[6][3];
int num[6];
bool chknum[6];
int N,M,K;
int res=98787987;
void count(){
int temp=0;
for(int i=1;i<=N;i++){
temp=0;
for(int j=1;j<=M;j++){
temp+=map[i][j];
}
if(res>temp) res=temp;
}
}
void rotate(int n){
int r=chk[n][0], c=chk[n][1], s=chk[n][2];
queue <int> q1;
for(int j=1;j<=s;j++){
int ny = r-j, nx = c-j;
q1.push(map[ny+1][nx]);
q1.push(map[ny][nx]);
for(int i=0;i<2*j;i++){
nx++;
q1.push(map[ny][nx]);
}
for(int i=0;i<2*j;i++){
ny++;
q1.push(map[ny][nx]);
}
for(int i=0;i<2*j;i++){
nx--;
q1.push(map[ny][nx]);
}
for(int i=0;i<2*j-2;i++){
ny--;
q1.push(map[ny][nx]);
}
ny=r-j,nx=c-j;
map[ny][nx]=q1.front();
q1.pop();
for(int i=0;i<2*j;i++){
nx++;
map[ny][nx]=q1.front();
q1.pop();
}
for(int i=0;i<2*j;i++){
ny++;
map[ny][nx]=q1.front();
q1.pop();
}
for(int i=0;i<2*j;i++){
nx--;
map[ny][nx]=q1.front();
q1.pop();
}
for(int i=0;i<2*j-1;i++){
ny--;
map[ny][nx]=q1.front();
q1.pop();
}
}
}
void dfs(int cnt){
if(cnt==K){
memcpy(map,copyMap,sizeof(map));
for(int i=0;i<K;i++){
rotate(num[i]);
}
count();
return;
}
for(int i=0;i<K;i++){
if(!chknum[i]){
chknum[i]=true;
num[cnt]=i;
dfs(cnt+1);
chknum[i]=false;
}
}
}
int main(){
freopen("input.txt","r",stdin);
cin>>N>>M>>K;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
cin>>copyMap[i][j];
}
}
for(int i=0;i<K;i++){
cin>>chk[i][0]>>chk[i][1]>>chk[i][2];
}
dfs(0);
cout<<res;
return 0;
}
'개발자 > algorithm' 카테고리의 다른 글
백준 17472번 : 다리 만들기 2 (c++) (0) | 2020.06.02 |
---|---|
SWEA 5644번 : 무선 충전 (c++) (0) | 2020.06.01 |
백준 17281번 : ⚾ (c++) (0) | 2020.05.29 |
SWEA 2383번 : 점심 식사시간 (c++) (0) | 2020.05.28 |
SWEA 5656번 : 벽돌 깨기 (c++) (0) | 2020.05.28 |