본문 바로가기
ps

[백준] 1022 - 소용돌이 예쁘게 출력하기

by kariskan 2022. 9. 4.

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

 

1022번: 소용돌이 예쁘게 출력하기

첫째 줄에 네 정수 r1, c1, r2, c2가 주어진다.

www.acmicpc.net

 

r과 c의 범위가 주어지고, 그에 맞는 출력을 반시계 방향 소용돌이 형태로 출력하는 문제이다.

 

먼저 현재 위치하는 r과 c를 이용해서, k라는 값을 구하였다.

이 k가 의미하는 바는 (0, 0)으로부터 몇 번째 테두리에 위치해있는가이다.

그러면 k를 이용해서 해당 테두리의 시작하는 값(가장 작은 값)인 start를 구할 수 있다.

 

0번째 테두리에는 1 = ((0 * 2 - 1) ^ 2 + 1)

1번째 테두리에는 2 = ((1 * 2 - 1) ^ 2 + 1)

2번째 테두리에는 10 = ((2 * 2 - 1) ^ 2 + 1)

..

 

이 start 값은 오른쪽 밑 모서리 바로 위에 위치하게 된다.

 

마지막으로는 해당 (r, c)가 동서남북 어느 테두리에 위치해있는지를 판별하였다.

판별한 후에는 r, c, k를 이용해서 정확히 어느번째의 수인지를 판별하였다.

 

#include <iostream>
#include <vector>
using namespace std;

int r1, c1, r2, c2;

int getN(int n) {
	int cnt = 0;
	while (n) {
		cnt++;
		n /= 10;
	}
	return cnt;
}

int main() {

	ios_base::sync_with_stdio(0);
	cout.tie(0);

	cin >> r1 >> c1 >> r2 >> c2;

	vector<int> v;
	int maxElement = 0;

	for (int i = 0; i <= r2 - r1; i++) {
		for (int j = 0; j <= c2 - c1; j++) {

			int r = r1 + i;
			int c = c1 + j;

			int k = max(abs(r), abs(c));
			int start = (k * 2 - 1) * (k * 2 - 1) + 1;
            
			if (r == -k) { //북
				v.push_back(start + k * 2 - 1 + (k - c));
			}
			else if (r == k) { //남
				v.push_back(start + k * 2 - 1 + k * 2 + k * 2 + (c + k));
			}
			else if (c == -k) { //서
				v.push_back(start + k * 2 - 1 + k * 2 + (r + k));
			}
			else if (c == k) { //동
				v.push_back(start + (k - r - 1));
			}
            
			maxElement = max(maxElement, v.back());
		}
	}

	int cnt = getN(maxElement);

	for (int i = 0; i <= r2 - r1; i++) {
		for (int j = 0; j <= c2 - c1; j++) {
			int num = getN(v[i * (c2 - c1 + 1) + j]);
			for (int k = 0; k < cnt - num; k++)cout << ' ';
			cout << v[i * (c2 - c1 + 1) + j] << ' ';
		}
		cout << '\n';
	}
}

'ps' 카테고리의 다른 글

[백준] 12764 - 싸지방에 간 준하  (0) 2022.09.05
[백준] 9489 - 사촌  (0) 2022.09.05
[백준] 2698 - 인접한 비트의 개수  (0) 2022.09.03
[백준] 6987 - 월드컵  (0) 2022.09.03
[백준] 2116 - 주사위 쌓기  (0) 2022.09.03

댓글