고대 유적지를 연구하던 인디아나 홍스는
유적지의 벽에 새겨진 엄청난 숫자들을 발견했다.
벽에 새겨진 숫자 중 일부는 비밀스러운 정보를 조회할 수 있는
열쇠 역할을 하는 비밀스러운 수이다.
오랜 연구 끝에 인디아나 홍스는 엄청난 숫자들이
특별한 규칙을 가지고 있다는 사실을 발견하였다.
엄청난 숫자들 중 의미있는 숫자들은
항상 2^k(0<=k) 형태로 적혀 있고,
그 외의 수들은 모두 비밀스러운 정보와는 관련 없다는 것이다.
인디아나 홍스를 도와 벽에 새겨진 숫자가
비밀스러운 정보인지 아닌지를 판별해보자!
첫 번째 줄에 새겨진 수가 주어진다.
이 수는 10^18
이하의 자연수이다.
주어진 수가 비밀스러운 정보를 가진 숫자라면 Yes
,
아니라면 No
를 출력한다.
32
Yes
1
Yes
10
No
입력값은 한 가지의 숫자가 들어오게 된다.
이 수는 10^18
이하의 자연수이다.
( ⚠️ 수의 범위를 알려준 이유를 한 번 생각해보자! )
입력값을 받아주기 위해서 변수 num
을 선언해주고,
int num = 0;
함수 scanf
를 이용해서 입력값을 받아준다.
scanf("%d", &num);
받아온 값이 제대로 들어왔는지 테스트해보는 것도 좋다.
성공적으로 값을 받아왔다면,
문제에서 요구하는 것에 대해 집중해보자.
이 문제가 요구하는 것은,
2의 거듭제곱으로 표현가능하다면 Yes
를 출력하고,
아니라면 No
를 출력하도록 작성하라는 것이다.
그렇다면 우선 홀수는 모두 제외될 것이므로,
num % 2 == 0
조건을 활용하는 것이 좋을 것 같다.
거듭제곱으로 표현이 가능하다는 것은
반복해서 나누었을 때, 나누어 떨어진다는 것을 의미하므로,
반복문을 활용하였다.
while (num % 2 == 0)
num /= 2;
2
의 배수를 반복해서 2
로 나누는 과정이 끝나면,
몫은 최종적으로 1
이 된다.
Yes
를 출력할지, No
를 출력할지를 두 가지 조건문으로 표현해주면 된다.
if (num == 1)
{
printf("Yes");
return (0);
}
else
{
printf("No");
return (0);
}
각 문구를 출력하고 return (0);
으로 프로그램을 종료시켜준다.
위와 같이 작성하게 되면,
문제에서 주어진 example case
에 대해서는 모두 통과가 되지만
제출을 할 때 Timeout
이 발생하게 된다.
입력값에 대해 다시 생각해볼 필요가 있다.
10^18
이하의 자연수이다.
해당 범위의 최댓값을 보면, 꽤나 큰 수라고 말할 수 있다.
처음에는 반복문에서 Timeout
이 발생했다고 생각했다.
그래서 얼마나 큰 수까지 구동이 되는지 확인해보았는데,
2^31
까지는 정상적으로 컴파일이 된다.
그런데 출력값이 바르게 나오지 않았다.
당연히 2
의 제곱수를 계산해서 넣었기 때문에
Yes
가 출력되어야하는데 No
가 출력되었다.
테스트를 하던 중, 새로운 이슈가 발생한 것이다.
그런데 불현듯 떠오른 생각이 있었다.
바로 type
이다.
입력값을 받아오는 변수 num
를 int
로 선언했었다.
입력값은 자연수만 해당되므로,
unsigned long int
로 바꾸어 테스트를 해보았더니,
Yes
가 출력되었다..!
그렇게 type
을 변경한 후 제출하였더니 All pass 를 받을 수 있었다!
조건에 대해서 다시 한 번 꼼꼼하게 살펴야겠다는 생각이 들었던 문제이다.