수의 비밀 ⭐1

Eugenie·2021년 4월 9일
0

solve_problem

목록 보기
2/2

위클리 비타알고 시즌2 코딩테스트 대비 입문편

고대 유적지를 연구하던 인디아나 홍스는
유적지의 벽에 새겨진 엄청난 숫자들을 발견했다.
벽에 새겨진 숫자 중 일부는 비밀스러운 정보를 조회할 수 있는
열쇠 역할을 하는 비밀스러운 수이다.
오랜 연구 끝에 인디아나 홍스는 엄청난 숫자들이
특별한 규칙을 가지고 있다는 사실을 발견하였다.
엄청난 숫자들 중 의미있는 숫자들은
항상 2^k(0<=k) 형태로 적혀 있고,
그 외의 수들은 모두 비밀스러운 정보와는 관련 없다는 것이다.

인디아나 홍스를 도와 벽에 새겨진 숫자가 
비밀스러운 정보인지 아닌지를 판별해보자!

✔️ 입력

첫 번째 줄에 새겨진 수가 주어진다.
이 수는 10^18 이하의 자연수이다.

✔️ 출력

주어진 수가 비밀스러운 정보를 가진 숫자라면 Yes,
아니라면 No 를 출력한다.


💡 example1

input
32
output
Yes

💡 example2

input
1
output
Yes

💡 example3

input
10
output
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 이다.
입력값을 받아오는 변수 numint 로 선언했었다.

입력값은 자연수만 해당되므로,
unsigned long int 로 바꾸어 테스트를 해보았더니,
Yes 가 출력되었다..!

그렇게 type 을 변경한 후 제출하였더니 All pass 를 받을 수 있었다!
조건에 대해서 다시 한 번 꼼꼼하게 살펴야겠다는 생각이 들었던 문제이다.

Github_Repository

profile
🌱 iOS developer

0개의 댓글