1. 문제 설명
정수 N으로 저장할 정수 바이트를 입력받는다. N의 값에 따라 long의 개수를 다르게 하여 int 자료형을 출력한다.
2. 접근법
1) 정수 N으로 정수 바이트 크기를 입력받는다.
2) N의 값에 따라 int 자료형을 출력한다.
1) 정수 N으로 정수 바이트 크기를 입력받는다.
정수형 변수 N을 선언한 뒤, scanf 함수를 통해 정수형 변수 N에 키보드로 입력한 값을 집어넣는다.
int N;
scanf("%d", &N);
scanf 함수에서 인자로 N이 아닌 N의 주소값인 &N이 들어가는 이유가 궁금하다면
2023.04.09 - [내가 배운 과목/C언어] - [C언어] scanf함수에 &를 사용하는 이유는 무엇일까? 를 확인해 보자.
2) N의 값에 따라 int 자료형을 출력한다.
4바이트 이하 정수는 long int, 4바이트 초과 8바이트 이하 정수는 long long int를 출력한다. 이를 계속 확장시켜 4의 배수+1마다 long을 하나씩 더 붙여주어 출력한다.
반복되는 부분은 long 출력이고 int 출력은 한 번이므로, long 출력을 반복문으로 하고 마지막에 int를 한 번 출력해 주면 되겠다.
우리가 C언어에서 쓸 수 있는 반복문은 대표적으로 for문이 있고, while문이 있고, do while문이 있다. long 출력문은 반드시 한 번은 수행되어야 하니(N이 최솟값 4일 때 long이 한 번 출력되므로), 필자는 한 번 수행하고 조건을 검사하는 do while문을 써 보기로 하였다.
long 출력문은 언제 반복되어야 할까? N이 작은 값일 때부터 생각해 보자. N이 4일 때 long 한번 출력, 4 초과 8 이하이면 long 두 번 출력, 9 < N <= 12이면 long 세 번 출력 ... ( = N이 5, 9, 13, ...일 때마다 long 출력이 반복되는 수가 증가한다)
N의 값이 4가 증가할 때 마다라는 것을 4의 배수로 생각할 수 있고, N / 4를 하면 N이 4의 몇배인지 구할 수 있다.
이를 생각하며 반복횟수 i와 N / 4와의 조건식을 세워 보면 되겠다.
N이 정확히 4의 배수가 아닌 +1일 때 반복횟수가 증가하므로
조건에서 N / 4 <= i가 아닌, 등호일때를 제외한 N / 4 < i로 식을 설정한다.
int i = 0;
do{
printf("long ");
i++;
} while (N / 4 > i);
*생각한 대로 써 보았으나 해당 코드는 오답이다. 왜 그럴까?
먼저 반복횟수를 정수 i로 선언하여 0으로 초기화 해 주고, long을 한 번 출력한다. 반복출력 시 띄어쓰기가 필요하므로 뒤에 공백을 하나 넣어준다. 그 후 i++를 통해 i의 값을 1 더해준다. 그리고 while 조건문을 통해 long을 반복 출력이 가능하도록 만들었다.
반복횟수가 0인 경우(반복 안하고 long 출력 처음에 하나인 경우)는 N이 4일때이고, 5부터는 반복횟수 i가 1이 되어도 N / 4가 i보다 크므로 반복한다. 한 번 반복 후 i값이 2가 되면 조건에 맞지 않아 탈출한다. 9의 경우 N/4가 2.25이므로 2번 반복해 처음 출력한 것과 합쳐 long이 세 번 출력되게 된다.
하지만 위 코드의 경우 실제로 돌려 보면 long이 설계한 것 보다 적게 반복된다. 이유는 무엇일까?
우리가 선언하고 사용하는 N이 정수형 변수이기 때문이다. 5 / 4의 결과는 1.25이지만 C언어 정수형 나눗셈에서는 몫만 남고 나머지는 버린다. 소수 부분이 탈락하는 것이다. 그리하여 1.xx의 경우 1로 계산되어 N이 8이 되기 전까지 long이 한 번만 출력된다.
그렇다면 N / 4의 결과가 정수형 나눗셈이 되지 않게 하면 되는데, 이는 명시적 형변환을 이용해 보도록 하겠다.
int i = 0;
do{
printf("long ");
i++;
} while ((double)N / 4 > i);
위 조건식에서 N 앞에 (double)이라는 자료형을 써 줌으로써 정수 N의 자료형을 int에서 double로 바꿔주었다.
형 변환이 일어났는데 직접 코드를 작성해 주어 일어났으므로 명시적 형변환 이라고 한다.
실수, 정수의 계산 결과는 실수를 따라가기 때문에 결과값 역시 소수부분이 버려지지 않아 제대로 계산되게 된다.
이후 int는 반복문 뒤에 따로 출력해 주면 되겠다.
3. 코드
#include <stdio.h>
int main(void) {
int n = 0, i = 0;
//visual studio의 경우 보안상의 이유로 함수 scanf_s를 사용하자
scanf("%d", &n);
do{
printf("long ");
i++;
} while ((double)n / 4 > i);
printf("int");
}
*visual studio의 경우 scanf를 보안상의 이유로 사용을 허용하지 않는다. scanf_s로 바꿔주자.
4. 테스트 및 결과
5. 결론 및 더 생각하기
필자는 do while문을 선택하여 한 번은 무조건 수행하고 반복할지 여부를 조건식으로 결정했다.
for문을 통해 처음 수행도 반복조건에 들어가게 해볼 수 있겠다. 한 번 해보자.
for (int i = 0; i < (double)N / 4; i++) {
printf("long ");
}
for문이 좀 더 깔끔하긴 하다.
'알고리즘 > 백준 문제풀이' 카테고리의 다른 글
[C언어] 쉽게 푸는 백준 11382번 꼬마 정민 문제 (0) | 2023.04.08 |
---|