본문 바로가기
Algorithm/시뮬레이션(구현)

17140 이차원 배열과 연산

by neohtux 2020. 8. 7.
728x90

https://www.acmicpc.net/problem/17140

 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

 

(풀이)

(풀이) 문제의 조건 R연산 , C연산

R연산 행의 개수 >= 열의 개수

C연산 행의 개수 < 열의 개수

 

풀이 순서

1. 이 문제의 모든 입력값은 3x3 행렬로 시작한다.

2. 가장 먼저 R,C연산에 대해 행 또는 열 정렬을 한다.

3. 행 또는 열에서 (원소수, 횟수)가 몇번 나왔는지 검사한다.

4. 3번에서 원소수, 횟수에 대해 정보를 가지고 있는 vector에 대해 정렬한다.

5. 해당 map에 정렬된 벡터를 저장한다.

6. 한번의 연산 마다 ans(Time)이 +1 씩 증가한다.

7. 연산횟수가 100이 초과 되면 -1을 출력하고 종료한다.

8. map[R][C] == K 답을 찾은경우 ans 를 출력하고 종료한다.

 

3번 과정의 (원소수,횟수)가 몇번 나왔는지 검사하는 함수 Get_calcuateRC(int idx, int size, char row_col)

매개변수

(1) 행 or 열의 시작 번호이다. 매개변수

(2) 행 or 열의 크기 이다. 매개변수

(3) row_col 은 'R' 연산인지 'C' 연산인지 구분자

 

4번 과정의 vector에 대해 (원소수,횟수) 를 정렬하는 함수

bool compare(pair<int,int> &a, pair<int,int>&b)

if(a.second == b.second) 횟수가 같다면

return a.first < b.first; 원소의 값을 기준으로 오름차순 정렬한다.

 

else return a.second < b.second; 횟수가 같지 않다면 횟수가 많을수록 뒤에 배치 한다.

 

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

using namespace std;
bool compare(pair<int, int> &a, pair<int, int> &b);
void Input();
void Solve();
vector<pair<int, int>> Get_calculateRC(int idx, int size, char row_col);

int map[101][101];
int num_count[101];
bool num_check[101];
int R, C, K;
int main(void)
{

	Input();
	Solve();

	return 0;
}
vector<pair<int, int>> Get_calculateRC(int idx,int size, char row_col)
{
	memset(num_count, 0, sizeof(num_count));
	memset(num_check, 0, sizeof(num_check));
	vector<pair<int, int>> result_vector;
	if (row_col == 'R') //행에서 원소, 횟수 검사
	{
		//해당 원소가 등장하는 횟수 검사.
		for (int i = 1; i <=size; ++i) 
		{
			num_count[map[idx][i]] += 1;
		}
		//원소, 횟수 추가
		for (int i = 1; i <= size; ++i)
		{
			int num = map[idx][i];
			if (num == 0) continue;

			int num_cnt = num_count[num];
			if (num_check[num] == false)
			{
				num_check[num] = true;
				result_vector.push_back(make_pair(num, num_cnt));
			}
		}

	}
	else //열에서 원소, 횟수 검사.
	{
		//해당 원소가 등장하는 횟수 검사.
		for (int i = 1; i <=size; ++i)
		{
			num_count[map[i][idx]] += 1;
		}
		//원소, 횟수 추가
		for (int i = 1; i <= size; ++i)
		{
			int num = map[i][idx];
			if (num == 0) continue;

			int num_cnt = num_count[num];
			if (num_check[num] == false)
			{
				num_check[num] = true;
				result_vector.push_back(make_pair(num, num_cnt));
			}
		}
	}

	return result_vector;
}
void Solve()
{
	int row_size = 3;
	int col_size = 3;
	int ans = 0;
	while (1)
	{
		if (map[R][C] == K)
		{
			cout << ans << '\n';
			return;
		}
		if (ans > 100)
		{
			cout << -1 << '\n';
			return;
		}
		//R연산
		if (row_size >= col_size)
		{
			//행 정렬
			//행에서 (원소 수, 횟수)가 몇번 나왔는지
			//(원소 수,횟수) 정렬
			// map에 저장

			int max_size = 0;
			for (int row_index = 1; row_index <= row_size; ++row_index)
			{
				//1.행에서 (원소 수, 횟수)가 몇번 나왔는지
				vector<pair<int, int>> v = Get_calculateRC(row_index, col_size, 'R');


				//2.(원소 수, 횟수) 정렬
				sort(v.begin(), v.end(), compare);

				//3 map에 저장 
				//(1) 0을 먼저 채운다

				for (int i = 1; i <= col_size; ++i)
					map[row_index][i] = 0;

				//(2) v를 map에 wirte 한다.

				int write_pos = 1; //write pos
				for (int j = 0; j < v.size(); ++j)
				{
					map[row_index][write_pos++] = v[j].first;
					map[row_index][write_pos++] = v[j].second;
				}

				//열이 최대 몇개인지 
				if (max_size < 2 * v.size())
					max_size = 2 * v.size();

			}
			col_size = max_size;
		}
		//C연산
		else
		{
			//열 정렬
			//열에서 (원소 수, 횟수)가 몇번 나왔는지
			//(원소 수,횟수) 정렬
			// map에 저장

			int max_size = 0;
			for (int col_index = 1; col_index <= col_size; ++col_index)
			{
				//1.행에서 (원소 수, 횟수)가 몇번 나왔는지
				vector<pair<int, int>> v = Get_calculateRC(col_index, row_size, 'C');


				//2.(원소 수, 횟수) 정렬
				sort(v.begin(), v.end(), compare);

				//3 map에 저장 
				//(1) 0을 먼저 채운다

				for (int i = 1; i <= col_size; ++i)
					map[i][col_index] = 0;

				//(2) v를 map에 wirte 한다.

				int write_pos = 1; //write pos
				for (int j = 0; j < v.size(); ++j)
				{
					map[write_pos++][col_index] = v[j].first;
					map[write_pos++][col_index] = v[j].second;
				}

				//행이 최대 몇개인지 
				if (max_size < 2 * v.size())
					max_size = 2 * v.size();

			}
			row_size = max_size;
		}
		ans += 1;
	}
}
void Input()
{
	cin >> R >> C >> K;

	for (int i = 1; i <= 3; ++i)
	{
		for (int j = 1; j <= 3; ++j)
			cin >> map[i][j];
	}
}

bool compare(pair<int, int> &a, pair<int, int> &b)
{
	if (a.second == b.second) // second 갯수가 같다면
		return a.first < b.first; //first 수의 오름차순

	else return a.second < b.second;
} 
300x250

'Algorithm > 시뮬레이션(구현)' 카테고리의 다른 글

17144 미세먼지 안녕!  (0) 2020.12.07
14891 톱니바퀴  (0) 2020.08.07
15685 드래곤 커브  (0) 2020.08.07

댓글