드디어 오늘의 코드가 10일차에 다다랐다.
Baekjoon / Problem No. 27960 (사격 내기)
Problem
A, B, C는 올해에도 예비군 훈련을 받으러 간다. 이번 예비군 훈련 과정 중에는 영점 사격이 있으며, 10개의 과녁 각각에 점수를 매겨 맞춘 과녁 점수의 총합을 측정한다. 과녁을 맞혔을 때, 과녁별로 각각 1점 / 2점 / 4점 / 8점 / 16점 / 32점 / 64점 / 128점 / 256점 / 512점을 얻는다. 과녁을 맞히지 않으면 해당 점수를 얻을 수 없으며, 각 과녁은 사람별로 최대 한 번만 맞힐 수 있다.
A, B와 C는 영점 사격 점수를 가지고 훈련 이후에 먹을 저녁 내기를 했다. A와 B는 각자 자신들의 총합 사격 점수를 공유했지만, C는 저녁 내기의 상황을 더 쫄깃하게 하고 싶었던지 점수를 공유하지 않고 아래와 같은 말을 했다.
"난 너희 둘 중 한 명만 맞힌 표적은 다 맞혔는데, 너희 둘 다 못 맞히거나 둘 다 맞힌 것은 전부 안 맞혔어."
A와 B는 이 말만으로는 도저히 C의 총합 점수를 알 수가 없어서 몰래 여러분에게 도움을 요청했다. C의 점수를 구해 A와 B를 도와주자!
Input

A와 B의 점수를 과녁의 점수 합으로 나타낼 수 없는 경우는 주어지지 않는다.
Output
C의 점수를 출력한다.
Solution
이 문제를 보면, 각 점수가 2의 거듭제곱 꼴로 나타나있다. 이는 2진수 표현을 할 때 나타나는 특징과 같다. 그리고 각 경우는 중복되지 않는다. (A와 B는 모두 각 과녁에 한 발씩만 적중시키므로). 이는 한 선수가 얻은 점수를 알 수 있다면, 비트로 바꾸어 연산하면 어떤 표적을 맞추었는지 알 수 있다.
이는 비트 마스킹의 개념과 일맥상통한다.
다음 표를 위를 선수 A, 아래를 선수 B로 두고, 각각 516, 129점을 맞추었다고 가정하자. 이를 배열로 나타내면,
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
다음과 같이 나타난다.
조금 더 축약하여 A와 B의 점수를 더하여 겹쳐보면
| 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
이와 같이 표현된다. (만약 둘 다 적중시킨 과녁이라면 당연히 2로 표현 될 것이다.) 그렇다면 여기서 "1"에 해당하는 곳에 대해 다시 10진수로 변형시키면(인덱스를 i라고 할때, i번째 배열의 원소는 2^i가 되어 각 부분을 더하면 변환이 완료된다.)
그것이 C의 점수일 것이다.
이제 A와 B는 C의 점수를 알게 되었고, 심판의 시간이 왔다. 만약 C가 졌다면, A,B를 귀찮게 한 괘씸죄로 저녁을 두 배로 사야할 것이다.
Code
#include <cstdio>
#include <math.h>
using namespace std;
int ScoreBoard[10] = {0,};
int main()
{
int A, B;
int sum = 0;
scanf("%d %d", &A, &B);
for (int i = 9; i >= 0; i--)
{
if (A >= pow(2, i))
{
A -= pow(2, i);
ScoreBoard[i]++;
}
if (B >= pow(2, i))
{
B -= pow(2, i);
ScoreBoard[i]++;
}
}
for (int j = 0; j <= 9; j++)
{
if (ScoreBoard[j] == 1)
sum += pow(2, j);
}
printf("%d", sum);
return 0;
}
Review
오늘의 코드가 오늘부로 10일차를 맞이하게 되었다.👏
문득 하나의 이야기가 떠오른다. 중국 허난성의 교사 구사오창은 단 10글자로 사직서를 썼고, 이는 이후 유명한 하나의 구절이 되었다.
<世界那么大,我想去看看>
"세상이 그렇게 넓다는데, 제가 한번 가보죠."라는 뜻이라고 한다.
코딩은 알아갈 수록 무궁무진하고, 지금 이 순간 역시 새로운 아이디어와 알고리즘들이 생겨나고 있다. 10일째 라는 것은 작은 발걸음에 불과하지만, 그 끝이 어디일지는 잘 모르겠다. 백엔드, 프론트엔드, 데이터베이스, 게임 프로그래밍 등 다양한 분야의 그 어딘가로 걸어가겠지만, 도착할지 멈춰설지 역시도 아직은 모르겠다.
어디에 도착할지는 몰라도 한번 걸어가본다고 생각하고 묵묵히 100일차, 1000일차, 어쩌면 한 평생 걸어가야 할지도 모르는 곳을 걸어가보는 것도 나름 나쁘지 않을것이다.
언젠가 뒤돌아 오면 이때동안 올려온 코드들을 보면서 "그땐 그랬지."하며 지금을 다시 떠올리겠지.
" 며칠 간 해외여행을 다녀오게 되었다. 포스팅이 불규칙적으로 올라오거나, 간단한 풀이로 끝날 수도 있을 것이다. 세상이 그렇게 넓다는데, 필자도 한번 다녀오려고 하니 미리 양해 바란다:) "
'오늘의 코드' 카테고리의 다른 글
| 오늘의 코드. 12일차 (백준/11758번 CCW) (2) | 2024.02.15 |
|---|---|
| 오늘의 코드. 11일차 (백준/2563번 색종이) (2) | 2024.02.14 |
| 오늘의 코드. 9일차 (백준/1929번 소수 구하기) (2) | 2024.02.12 |
| 오늘의 코드. 8일차 (백준/1010번 다리놓기) (0) | 2024.02.11 |
| 오늘의 코드. 7일차 (백준/13909번 창문 닫기) (2) | 2024.02.10 |