※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2041번 문제인 숫자채우기이다.
문제는 아래 링크를 확인하자.

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

 

2041번: 숫자채우기

N×M 크기의 격자에 적절히 수를 채우려 한다. 단, 인접한 수들의 차이로 1부터 (2NM-N-M)까지의 수가 한 번씩 나오도록 채우려 한다. N=2, M=2인 경우를 예로 들면 다음과 같은 방법이 있다. 위와 같

www.acmicpc.net

R행 C열 격자가 주어질 때, 격자의 인접한 칸에 적힌 수들의 차가 1부터 RC-R-C까지 전부 나올 수 있게 격자를 채우는 문제이다.

 

격자 자체에 어떻게 수를 배치할지 대신, "인접한 두 칸 사이의 차"들을 "칸들이 맞닿은 경계"에 어떻게 배치할지를 생각하면 문제를 좀 더 편하게 풀 수 있다.

 

문제의 조건에 맞게 채울 수 있는 방법을 하나 발견하고, 이를 구현해 제출하자.

 

아래는 글쓴이의 풀이를 서술해두었다. 직접 풀기를 포기한 사람만 읽자.

더보기

1. 첫 칸에 0을 놓고, 행방향으로 (C-1)개의 (아직 등장하지 않은 차)를 부호를 바꿔가며 더해나간다.

2. 다음으로, 다음 행의 각 열의 칸을 이전 행의 각 칸의 숫자에 (아직 등장하지 않은 차)를 부호를 바꿔가며 더해나간다.

3. 2를 마지막 행까지 반복한다.

 

이것을 반복하는 것으로 문제에서 요구하는(단, 음수가 들어있으니 이대로 제출할 수는 없다) 격자를 만들 수 있다.

아래는 5행 5열 격자를 채운 예시이다.

 

0 1 -1 2 -2
5 -5 6 -6 7
-9 10 -10 11 -11
14 -14 15 -15 16
-18 19 -19 20 -20

 

첫 행에서 1부터 4까이의 차가, 첫 행과 둘째 행 사이 열의 차에서 5부터 9까지의 차가 등장하는 모습을 볼 수 있다.

또한, 둘째 행에서 10부터 13까지의 차가, 둘째 행과 셋째 행 사이 열의 차에서 14부터 18까지의 차가 등장하는 모습을 볼 수 있다.

 

이제 위 표의 수들이 모두 수가 양수가 되게끔 상수를 더해 문제를 해결하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int R, C;

int arr[1001][1001];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> R >> C;

	int k = 1;
	for (int r = 1; r <= R; r++) {
		if (r > 1) {
			if (arr[r - 1][1] > 0) arr[r][1] = arr[r - 1][1] - k;
			else arr[r][1] = arr[r - 1][1] + k;
			k += C;
		}
		for (int c = 2; c <= C; c++) {
			if (arr[r][c - 1] > 0) arr[r][c] = arr[r][c - 1] - (k++);
			else (arr[r][c] = arr[r][c - 1] + (k++));
		}
	}

	for (int r = 1; r <= R; r++) {
		for (int c = 1; c <= C; c++) {
			cout << arr[r][c] + 1000000007 << ' ';
		}
		cout << '\n';
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1637 // C++] 날카로운 눈  (0) 2022.07.08
[BOJ 1646 // C++] 피이보나치 트리  (0) 2022.07.07
[BOJ 11058 // C++] 크리보드  (0) 2022.07.05
[BOJ 5052 // C++] 전화번호 목록  (0) 2022.07.04
[BOJ 14714 // C++] 홍삼 게임 (Easy)  (0) 2022.07.03

+ Recent posts