SWExpertAcademy의 촛불 이벤트(9843 / D5) 문제이다.
[ 문제풀이 ]
양초의 갯수를 이용해서 몇 단 크기의 촛불 삼각형을 만들 수 있는지 구해야 하는 문제이다.
양초의 갯수가 어떤 특징을 갖는지 먼저 알아보자.
먼저, 양초가 1개 존재한다면 1단 촛불 삼각형을 만들 수 있다.
양초가 2개가 존재한다면 ?? 촛불 삼각형을 만들수가 없다.
양초가 3개가 존재한다면 ?? 2단 촛불 삼각형을 만들 수 있다.
.
위의 그림에서 삼각형 하나를 '양초' 라고 표현했을 때, 위의 그림과 같이 양초 3개로는 2단 촛불 삼각형을 만들 수 있다.
양초가 4개, 5개가 있다면 촛불 삼각형을 만들 수 없고, 양초가 6개가 있을 때는 다음과 같이 3단 촛불 삼각형을 만들 수가 있다.
.
그럼 여기서 양초의 갯수가 어떤 숫자일 때 촛불 삼각형이 되는지 안되는지 부터 알아보자. 몇 단인지는 그 후에 알아보자.
위에서 양초가 1개 ~ 6개인 경우를 한번 적어봤는데, 촛불 삼각형이 되는 경우는 [ 1 , 3 , 6 ] 개의 양초가 존재할 때만
가능했다.
그런데 ! 위의 [ 1 , 3 , 6 ] 숫자들의 공통점을 찾아보면 바로 "등차수열로 표현이 가능한 숫자" 라는 것이다.
1 = 1
3 = 1 + 2
6 = 1 + 2 + 3
위의 특징을 생각해보면, 아마 그 다음 4단 촛불 삼각형은 10개의 양초가 필요할 것이다.
10 = 1 + 2 + 3 + 4
우리에게는 양초의 갯수 N이 주어진다. 그리고 몇 단 촛불삼각형을 만들 수 있냐 라고 문제에서 물어봤는데, 우리가 구해야 하는 것은 다음과 같이 2가지가 있다.
1. 주어진 N이 등차수열로 표현이 가능한가 ?
2. 등차수열로 표현이 가능하다면, 이를 만족시키는 값이 얼마인가 ?
이렇게 2가지를 구하면 된다.
그럼 등차수열로 표현이 가능하다 라는 것은 무엇을 의미할까 ??
바로 a * (a + 1) / 2 = N 을 만족시키는 a값이 존재한다는 것을 의미한다. 이 때, a값을 우리에게 묻고 있는 것이다.
만약, 만족시키는 a값이 없다면 -1을 출력하면 되는 것이다.
그럼, a * (a + 1) / 2 = N 을 만족시키는 a 값을 찾아야 한다. 어떻게 찾아야할까 ??
먼저, 식을 대충 한번만 정리해보면, a * (a + 1) = N * 2 로 정리해볼 수 있다.
그럼, N * 2 = K 라고 바꿔보면, K = a * (a + 1)이 된다.
본인은 여기서 "수의 특징" 을 이용해서 접근해보았다.
K에 루트를 씌운 값을 작은 k로 표현해보자.
그럼 구하고자 하는 숫자 'K'는 k^2 <= K < (k + 1)^2 이라는 특징이 있다.
하나의 예를 들어보자. K = 5라고 가정해보면, 루트를 씌운 값인 k = 2.xxx 가 된다. 소수점은 떼고 정수만 구해보자.
그럼 k = 2가 된다.
2^2 <= 5 < (2 + 1)^2 == "4 <= 5 < 9" 가 성립하게 된다.
즉 ! 우리는 이 루트를 씌운 값을 통해서 a값을 구할 수가 있다.
1. K의 값(N * 2)에 루트를 씌운다.
2. 루트를 씌운 값에서, 소수점은 다 버리고 정수만 뽑아 온다. 이 때 나온 정수를 a라고 하겠다.
3. a * a + 1 = K 인지 확인 한다.
만약 3번에서 성립 한다면, 해당 a를 출력하면 되고, 성립이 하지 않는다면 -1을 출력하면 된다.
우리가 했던 숫자들을 예시로 한번 테스트를 해보자.
숫자 '6'은 3단 촛불삼각형을 만들 수 있었다.
그럼, 순서대로 진행해보자.
1. a * (a + 1) == 6 * 2 가 성립하는 a값을 찾아보자.
2. a * (a + 1) = 12 이고, 12에 루트를 씌워보자.
3. 12에 루트를 씌운값 = 3.xxx = 3
4. 3 * 4 = 12가 성립하는지 확인해보자.
5. 성립함으로 a = 3. 즉 ! 3단 촛불삼각형을 만들 수 있다.
그럼 8로 한번 진행해보자.
1. a * (a + 1) == 8 * 2 가 성립하는 a값을 찾아보자.
2. a * (a + 1) = 16 이고 , 16에 루트를 씌워보자.
3. 16에 루트를 씌운 값 = 4
4. 4 * 5 = 16 이 성립하는지 확인해보자.
5. 성립하지 않으므로, '8'이라는 숫자는 등차수열로 표현이 불가능하다는 것을 의미하고, 촛불 삼각형을 만들 수 없음을 의미한다.
위와 같은 특징으로 문제를 해결할 수 있다.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <iostream> #include <cstring> #include <cmath> #define endl "\n" using namespace std; long long N, Answer; void Initialize() {} void Input() { cin >> N; } void Solution() { long long Candidate = sqrt(N * 2); if (Candidate * (Candidate + 1) == N * 2) Answer = Candidate; else Answer = -1; } void Solve() { int Tc; cin >> Tc; for (int T = 1; T <= Tc; T++) { Initialize(); Input(); Solution(); cout << "#" << T << " " << Answer << endl; } } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ SWEA Code ] > # SWEA - ' 카테고리의 다른 글
[ SWEA 9092 ] 마라톤 (C++) (0) | 2020.09.14 |
---|---|
[ SWEA 7812 ] 옥히의 OK! 부동산 (C++) (0) | 2020.09.05 |
[ SWEA 4740 ] 밍이의 블록 게임 (C++) (0) | 2020.08.29 |
[ SWEA 7730 ] 나무 깎는 홍준 (C++) (0) | 2020.08.27 |
[ SWEA 9015 ] 배열의 분할 (C++) (0) | 2020.08.25 |