본문 바로가기

스터디/코딩

[ 코딩 도장 : C ] Unit 38. 포인터와 배열 응용하기 : 연습문제 / 심사문제

38.6 연습문제 : 포인터에 할당된 메모리를 3차원 배열처럼 사용하기

문제) 다음 소스 코드를 완성하여 포인터에 할당된 메모리를 높이 2, 세로 크기 3, 가로 크기 5인 3차원 배열처럼 사용할 수 있도록 만드세요.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int depth;
    int row;
    long long*** m = malloc(sizeof(long long**) * 2);

    for (depth = 0; depth < 2; depth++)
    {
        m[depth] = malloc(sizeof(long long*) * 3);

        for (int row = 0; row < 3; row++)
        {
            m[depth][row] = malloc(sizeof(long long) * 5);
        }
    }

        m[1][2][4] = 100;

    printf("%lld\n", m[1][2][4]);

    for (depth = 0; depth < 2; depth++)
    {
        for (row = 0; row < 3; row++)
        {
            free(m[depth][row]);
        }

        free(m[depth]);
    }

        free(m);

    return 0;
}

 

 

38.7 심사문제 : 단위 행렬 만들기

문제) 표준 입력으로 정사각행렬의 크기가 입력됩니다(입력 값의 범위는 2~10). 입력된 크기만큼의 단위행렬을 출력하는 프로그램을 만드세요(scanf 함수 호출 전에 문자열을 출력하면 안 됩니다). 숫자와 숫자 사이는 공백으로 띄웁니다.

단위행렬은 왼쪽 위부터 오른쪽 아래까지의 대각선(주대각선)이 1이며 나머지는 모두 0인 행렬입니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int size;
    scanf("%d", &size);

    int** m = malloc(sizeof(int*) * size);
    for (int i = 0; i < size; i++)
    {
        m[i] = malloc(sizeof(int) * size);
        memset(m[i], 0, sizeof(int) * size);
    }

    for (int i = 0; i < size; i++)
    {
        m[i][i] = 1;
    }

    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            printf("%d ", m[i][j]); 
        }

        printf("\n");
    }

    for (int i = 0; i < size; i++)
    {
        free(m[i]);
    }

    free(m);

    return 0;
}

 

38.8 심사문제 : 지뢰찾기

문제) 표준 입력으로 행렬의 크기 m, n과 문자(char) 행렬이 입력됩니다(m과 n의 범위는 3~10). 입력된 m, n은 공백으로 구분되며 행렬 안에서 *은 지뢰이고 .은 지뢰가 아닙니다. 지뢰가 아닌 요소에는 인접한 지뢰의 개수를 출력하는 프로그램을 만드세요(scanf 함수 호출 전에 문자열을 출력하면 안 됩니다).

여러 줄을 입력 받으려면 다음과 같이 for 반복문으로 scanf를 반복 호출하면 됩니다.

for (int i = 0; i < m; i++)
{
    scanf("%s", matrix[i]);
}

 

행렬의 가로 공간에는 문자열이 들어갑니다. 따라서 메모리를 할당할 때는 n + 1(가로 크기 + 1)만큼 할당하여 NULL이 들어갈 공간까지 확보해야 합니다. 이 부분은 'Unit 39 문자열 사용하기'(515쪽), 'Unit 40 입력 값을 문자열에 저장하기'(527쪽)에서 자세히 설명하겠습니다.

이 문제는 지금까지 심사문제 중에서 가장 어렵습니다. 처음 풀어보는 경우 대략 두 시간은 걸립니다. 시간을 두고 천천히 고민해서 풀어보세요. 지금까지 학습한 내용을 모두 동원해야 풀 수 있으며 막힐 때는 지금까지 학습한 내용을 다시 복습하면서 힌트를 찾아보세요.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int m, n;
    int i, j;

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

    char** matrix = malloc(sizeof(char*) * m);

    for (i = 0; i < m; i++)
    {
        matrix[i] = malloc(sizeof(char) * (n + 1)); 
        memset(matrix[i], 0, sizeof(char) * (n + 1));
    }

    for (i = 0; i < m; i++)
    {
        scanf("%s", matrix[i]);
    }

    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++) 
        {
            if (matrix[i][j] == '*') 
            {
                printf("%c", matrix[i][j]);
                continue;
            }

            else
            {
                matrix[i][j] = 0;

                for (int x = i - 1; x <= i + 1; x++)
                {
                    for (int y = j - 1; y <= j + 1; y++)
                    {
                        if (x < 0 || x >= n || y < 0 || y >= n)
                            continue;

                        else if (matrix[x][y] == '*')
                            matrix[i][j] += 1;
                    }

                }
                printf("%d", matrix[i][j]);
            }
        }
        printf("\n");
    }

    for (int i = 0; i < m; i++)
        free(matrix[i]);

    free(matrix);

    return 0;

}