거의 알고리즘 일기장

백준 17406번 _ 배열 돌리기 4 본문

알고리즘 문제풀이

백준 17406번 _ 배열 돌리기 4

건우권 2020. 10. 12. 00:00

www.acmicpc.net/problem/17406

 

17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net


코드

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

#define MAX_VAL 987654321

using namespace std;

class RotateData
{
public:
	int r;
	int c;
	int s;
	RotateData(){}
	RotateData(int r_in, int c_in, int s_in):r(r_in), c(c_in), s(s_in){}
};

int N, M, K;
int map[50][50];
int oriMap[50][50];
vector<RotateData> rotateDataes;

void printMap()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cout << map[i][j] << ' ';
		}
		cout << '\n';
	}
	cout << '\n';
}

void mapInit()
{
	for (int i = 0; i < N; i++)
		for (int j = 0; j < M; j++)
			map[i][j] = oriMap[i][j];
}

void Rotate(int r, int c, int s)
{
	pair<int, int>leftUpPos = {r-s, c-s};
	pair<int, int>rightDownPos = {r+s, c+s};

	while (1)
	{
		//printMap();

		if (leftUpPos == rightDownPos)
			break;

		int ns = rightDownPos.second - leftUpPos.second;

		vector<int> temp;
		//저장
		//line 1
		for (int i = 0; i < ns; i++)
			temp.push_back(map[leftUpPos.first][leftUpPos.second + i]);
		//line 2
		for (int i = 0; i < ns; i++)
			temp.push_back(map[leftUpPos.first + i][rightDownPos.second]);
		//line 3
		for (int i = 0; i < ns; i++)
			temp.push_back(map[rightDownPos.first][rightDownPos.second - i]);
		//line 4
		for (int i = 0; i < ns; i++)
			temp.push_back(map[rightDownPos.first - i][leftUpPos.second]);

		//회전한 값 넣기
		//line 1
		for (int i = 1; i <= ns; i++)
			map[leftUpPos.first][leftUpPos.second + i] = temp[i - 1];
		for (int i = 1; i <= ns; i++)
			map[leftUpPos.first + i][rightDownPos.second] = temp[ns + i - 1];
		for (int i = 1; i <= ns; i++)
			map[rightDownPos.first][rightDownPos.second - i] = temp[2*ns + i - 1];
		for (int i = 1; i <= ns; i++)
			map[rightDownPos.first - i][leftUpPos.second] = temp[3*ns + i - 1];

		leftUpPos.first += 1;
		leftUpPos.second += 1;
		rightDownPos.first -= 1;
		rightDownPos.second -= 1;
	}
}

int getMinVal()
{
	int ret = MAX_VAL;
	for (int i = 0; i < N; i++)
	{
		int val = 0;
		for (int j = 0; j < M; j++)
			val += map[i][j];

		ret = min(ret, val);
	}
	return ret;
}

int main()
{
	int answer = MAX_VAL;

	//map 입력
	cin >> N >> M >> K;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			int mapval;
			cin >> mapval;
			oriMap[i][j] = map[i][j] = mapval;
		}
	}

	//돌리기
	for (int i = 0; i < K; i++)
	{
		int r, c, s;
		cin >> r >> c >> s;
		RotateData rotateData(r - 1, c - 1, s);
		rotateDataes.push_back(rotateData);
	}
	
	//임의로 다돌려봐야함.
	vector<int> temp;
	temp.resize(K);
	for (int i = 0; i < K; i++)
		temp[i] = i;
	do
	{
		mapInit();
		for (auto ele : temp)
		{
			auto curRotateData = rotateDataes[ele];
			Rotate(curRotateData.r, curRotateData.c, curRotateData.s);
		}
		answer = min(answer, getMinVal());
	} while (next_permutation(begin(temp), end(temp)));
	
	cout << answer << '\n';

	return 0;
}
반응형

'알고리즘 문제풀이' 카테고리의 다른 글

백준 5213번 _ 과외맨  (0) 2020.10.12
백준 16988번 _ Baaaaaaaaaduk2 (Easy)  (0) 2020.10.12
백준 1400번 _ 화물차  (0) 2020.10.11
백준 19236번 _ 청소년 상어  (0) 2020.10.11
백준 19237번 _ 어른 상어  (0) 2020.10.09
Comments