2017년 1월 5일 목요일

12. 예제 문제와 풀이

12. 예제 문제와 풀이

함수와 배열과 포인터, 그리고 지금까지 배운 내용을 토대로 예제 문제를 풀어봅니다.




1) 정사각형으로 출력

문제

입력받은 수를 정사각형으로 출력하세요.
정사각형의 크기는 4 * 4입니다.
이때 입력되는 수는 모두 1자리 또는 2자리 자연수이며 정사각형을 출력할 때 숫자를 %2d로 출력하세요.
예시
입력: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

답안 예시

#include <stdio.h>

int main(void)
{
    int num[16];
    int i = 0;

    printf("입력: ");

    for (i = 0; i < 16; i++)
    {
        scanf("%d", &num[i]);
    }

    for (i = 0; i < 16; i++)
    {
        if (i % 4 == 0)
        {
            printf("\n");
        }
        printf("%2d ", num[i]);
    }

    return 0;
}
쉽게 표현하고자 입력받는 for문과 출력하는 for문을 분리하였으나 사실 합쳐도 무방합니다.
#include <stdio.h>

int main(void)
{
    int num[16];
    int i = 0;

    printf("입력: ");

    for (i = 0; i < 16; i++)
    {
        scanf("%d", &num[i]);
        if (i % 4 == 0)
        {
            printf("\n");
        }
        printf("%2d ", num[i]);
    }

    return 0;
}



2) 제곱근 구하기

문제

자연수의 제곱근을 구하는 함수 sqrtInteger(int num)을 만드세요.
이때, 함수의 결과값은 double로 합니다.
그리고 이 함수를 이용해 1부터 n까지 수의 제곱근을 출력하세요.
제곱근의 정확도는 0.01이내로 하며 출력도 소숫점 2자리까지 합니다. (%.2f로 출력합니다.)
예시
몇까지 계산할까요: 100
1의 제곱근: 1.00
(생략)
100의 제곱근: 10.00

답안 예시

#include <stdio.h>

double sqrtInteger(int num);

int main(void)
{
    int max, i;

    printf("몇까지 계산할까요: ");
    scanf("%d", &max);

    for (i = 1; i <= max; i++)
    {
        printf("%d의 제곱근: %.2f\n", i, sqrtInteger(i));
    }

    return 0;
}

double sqrtInteger(int num)
{
    double temp = 1;

    while (-0.01 > (temp * temp - num) || (temp * temp - num) > 0.01)
    {
        temp = 0.5 * (temp + num / temp);
    }

    return temp;
}
예시의 경우 제곱근을 뉴튼-랩슨법을 이용해서 구했지만 여러가지 방법이 가능합니다.
인터넷에 검색하거나 스스로 연구해서 제곱근을 특정 정확도 내로 구하는 법을 생각해보세요.

(참고) a의 n제곱근 구하기

#include <stdio.h>

double power(double a, int n)
{
    if (a == 0) { return 0; }

    int i = 0;
    double ret = 1;

    for (i = 0; i < n; i++)
    {
        ret *= a;
    }

    return ret;
}

double root(double a, int n, double precision)
{
    double ret = 1;

    while ((power(ret, n) - a) < -precision || (power(ret, n) - a) > precision)
    {
        ret = ret * (n - 1) / n + a / (n * power(ret, n - 1));
    }

    return ret;
}

int main()
{
    int a, n;

    scanf("%d %d", &a, &n);

    printf("%.4f\n", root(a, n, 0.0001));

    return 0;
}



3) 소수 출력하기

문제

1부터 입력받은 수 까지 소수를 모두 찾아 출력하는 프로그램을 만드세요.
주어진 자연수가 소수인지 검사하는 isPrime함수를 만들어 사용하세요.
그리고 소수를 몇 개 찾았는지도 출력하세요.
예시
어디까지 소수를 찾을까요: 20
소수: 2 3 5 7 11 13 17 19
총 8개의 소수를 찾았습니다!

답안 예시

bool isPrime(int num);

int main()
{
    int i = 0, count = 0, max = 0;

    printf("어디까지 소수를 찾을까요: ");
    scanf("%d", &max);

    printf("소수: ");

    for (i = 2; i <= max; i++)
    {
        if (isPrime(i))
        {
            printf("%d ", i);
            count++;
        }
    }

    printf("\n");
    printf("총 %d개의 소수를 찾았습니다!\n", count);

    return 0;
}

bool isPrime(int num)
{
    int i;

    for (i = 2; i * i <= num; i++)
    {
        if (num % i == 0)
            return false;
    }

    return true;
}
이 경우 1부터 루트n까지 검사하는 방법을 사용했는데, 수가 커지면 다른 방법들이 더 빠를 수 있습니다.
어떤 알고리즘들이 소수를 찾을 수 있는지 찾아보세요.



댓글 없음:

댓글 쓰기