코테

백준 단계별로 풀어보기 (7)

hhzn 2025. 3. 18. 20:39

이번 단계는 2차원 배열에 관한 문제들이 수록되어 있다. 
STL에서 제공하는 자료구조(사실 오직 vector)들을 사용하면서 간단하게 풀었다.

 


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

 

2738번 행렬 덧셈

 

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	int n, m;
	cin >> n >> m;

	vector<vector<int>> v(n, vector<int>(m, 0));	// n*m 행렬 0으로 초기화

	for (int i = 0; i < 2; ++i) {
		for (int r = 0; r < n; ++r) {
			for (int l = 0; l < m; ++l) {
				int num;
				cin >> num;
				v[r][l] += num;
			}
		}
	}
	
	for (auto vec : v) {
		for (int n : vec)
			cout << n << ' ';
		cout << '\n';
	}
}

입력으로 주어진 행렬의 크기에 맞게 2차원 배열을 vector로 생성한다.
차례대로 들어오는 원소의 값들을 해당 벡터의 맞는 자리에 += 연산을 이용해서 더해준다. 

vector<vector<int>> 으로 2차원 배열을 생성할 수 있다. 

생성자를 호출할 때, 초기 원소의 개수, 채워넣을 값을 넘기면 모든 원소를 특정 값으로 초기화 할 수 있다. 

일단 int 타입을 m만큼, 0을 넣은 벡터를 다시 n만큼 만들면 2차원 배열을 손쉽게 선언할 수 있다.


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

 

2566번 최댓값

 

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

using namespace std;

int main()
{
	vector<vector<int>> v(9, vector<int>(9, 0));

	for (int i = 0; i < 9; ++i) {
		for (int j = 0; j < 9; ++j) {
			cin >> v[i][j];
		}
	}
	auto result = max_element(v.begin(), v.end(), [](const auto& a, const auto& b) {
		auto i = max_element(a.begin(), a.end());
		auto j = max_element(b.begin(), b.end());

		return *i < *j;
		});
	// 가장 큰 수가 들어있는 행을 찾음.
	int row = result - v.begin() + 1;	// 행
	auto result2 = max_element(result->begin(), result->end());	// 가장 큰 수의 반복자
	int col = result2 - result->begin() + 1;	// 열

	cout << *result2<< '\n' << row<< ' ' << col;
}

문제에서 주어진 9x9 크기의 2차원 배열을 정의하여 알맞은 위치에 값을 정의한다. 

먼저 가장 큰 값이 들어있는 행을 찾는다.

vector<int> 의 vector 이기 때문에 큰 값을 반환하는 기준(함수)을 직접 작성해야 한다.

두 개의 vector<int> 의 가장 큰 원소를 비교해서 큰 값이 들어있는 vector<int> 를 반환하도록 한다.

해당 행의 반복자를 받아 몇 번째 행인지 찾을 수 있다.
행을 찾았다면 열은 쉽다. 해당 행에서 가장 큰 값이 들어있는 반복자를 받아서 몇 번째 열인지 알 수 있다.
찾은 값과 행과 열을 순서대로 출력하면 된다.

(가장 큰 값은 max_element 를 이용해서 찾는다. )


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

 

10798번 세로읽기

 

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
	vector<vector<char>> v(5, vector<char>(15, ' '));
	
	for (int i = 0; i < 5; ++i) {
		string str;
		cin >> str;
		for (int j = 0; j < str.length(); ++j) {
			v[i][j] = str[j];				
		}
	}

	// 공백을 저장해두고 공백이면 출력 안하기
	
	for (int i = 0; i < 15; ++i) {
		for (int j = 0; j < 5; ++j) {
			if (v[j][i] != ' ')
				cout << v[j][i];
		}
	}
}

char 2차원 배열을 선언한다. 모든 원소가 ' ' 인 5행 15열 2차원 배열이 생성되었다.

주어진 입력의 조건은 각 줄에는 최소 1개, 최대 15개의 글자들이 주어지기 때문에 최대값에 맞게 배열의 크기를 선언했다.

5개의 단어가 한 줄씩 띄어서 입력되기 때문에 string 을 5번 입력받는다. 입력받은 길이만큼 char 를 배열에 저장한다.

 

저장된 원소를 순회하는 방법으로는 단순히 열 우선으로 접근하도록 하면 된다. for 문을 이용하여 열 우선으로 접근하되, 원소를 저장하지 않아 초기값인 ' ' 인 곳은 출력하지 않도록 한다.

 

나는 초기값을 ' ' 로 지정했지만 ' '말고도 입력으로 주어지는 글자인 영어 대문자 'A' 부터 'Z', 영어 소문자 'a' 부터 'z', 숫자 '0' 부터 '9' 가 아닌 char 면 상관 없다. 

 


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

 

2563번 색종이

 

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

using namespace std;

int main()
{
	int num; 
	cin >> num;

	vector<vector<bool>> v(100, vector<bool>(100, false));
	
	for (int i = 0; i < num; ++i) {
		int x, y;
		cin >> x >> y;

		for (int a = x; a < x + 10; ++a) {
			for (int b = y; b < y + 10; ++b) {
				v[a][b] = true;
			}
		}
	}

	int cnt = 0;

	for (const auto& vec : v) {
		const int curr_vec_cnt = count(vec.begin(), vec.end(), true);
		cnt += curr_vec_cnt;
	}

	cout << cnt;

}

 

초기값이 false 인 100x100 사이즈의 2차원 bool 배열을 생성한다.

 

입력으로 색종이의 시작점이 주어지면 해당 원소부터 10 행까지, 10열 까지 모두 true 로 저장한다.

모든 행을 순회해서 true 의 수를 더한다. 해당 값을 출력하면 된다. 

count 를 사용해서 true 의 개수를 얻을 수 있다. 

 


** 오류 지적은 환영입니다. ^^ **