#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int m, n; //가로, 세로 변수 지정
scanf("%d %d", &m, &n);
char **matrix = malloc(sizeof(char *) * m); // 세로
for (int i = 0; i < m; i++)
{
matrix[i] = malloc(sizeof(char) * n + 1); // 가로 [NULL고려한 (n + 1) 대입]
memset(matrix[i], 0, sizeof(char) * n + 1); // 0으로 전부 초기화
}
int **count = malloc(sizeof(int *) * m);
for (int i = 0; i < m; i++)
{
count[i] = malloc(sizeof(int) * n + 1);
memset(count[i], 0, sizeof(int) * n + 1);
}
printf("지뢰찾기프로그램을 위한 문자를 모두 입력하세요.\n");
for (int i = 0; i < m; i++)
{
scanf("%s", matrix[i]);
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] == '*')
{
if (matrix[i - 1][j] == '.' && (i - 1) >= 0)
count[i - 1][j]++;
if (matrix[i - 1][j - 1] == '.' && (i - 1) >= 0 && (j - 1) >= 0)
count[i - 1][j - 1]++;
if (matrix[i - 1][j + 1] == '.' && (i - 1) >= 0 && (j + 1) <= n-1)
count[i - 1][j + 1]++;
if (matrix[i][j - 1] == '.' && (j - 1) >= 0)
count[i][j - 1]++;
if (matrix[i][j + 1] == '.' && (j + 1) <= n-1)
count[i][j + 1]++;
if (matrix[i + 1][j] == '.' && (i + 1) <= m-1)
count[i + 1][j]++;
if (matrix[i + 1][j - 1] == '.' && (i + 1) <= m-1 && (j - 1) >= 0)
count[i + 1][j - 1]++;
if (matrix[i + 1][j + 1] == '.' && (i + 1) <= m-1 && (j + 1) <= n-1)
count[i + 1][j + 1]++;
}
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (matrix[i][j] == '*')
printf("*");
else
printf("%d", count[i][j]);
}
printf("\n");
}
for (int i = 0; i < m; i++)
{
free(count[i]);
}
free(count);
for (int i = 0; i < m; i++)
{
free(matrix[i]);
}
free(matrix);
return 0;
}
제가 이렇게 했는데 문자 입력할때 별표시를 맨 윗줄이나 맨 아랫줄에다가 넣으면 오류가나네요,, 왜 그런지 잘 모르겠습니다..
ex) 3 X 3 할 떄,
...
..*
... << 이건 잘 되는데
..* ...
... ...
... 또는 ..* << 이런건 오류가 나면서 안되네요..
지뢰찾기 문제는 평가에서 테두리 셀을 배열 인덱스 범위를 벗어나지 않으면서 처리할 수 있는지 묻는 문제입니다.
심사문제 제출 후에 표시되는 해설을 보면
행렬이 준비되면 m, n만큼 반복하면서 요소가 *이면 continue로 건너뛰고 *이 아니면 문자 '0'을 넣습니다(continue는 '30.2 continue로 코드 실행 건너뛰기' 참조). 이제 이 요소 주변 8개를 탐색하여 *이면 요소의 개수를 1씩 증가시키면 됩니다.
문제를 푸는 방법은 여러 가지가 있을 수 있습니다. 코딩보단 접근 방식을 달리하는 게 좋습니다.
continue를 써서 푸는 게 좋다는 건 그게 보편적으로는 더 쉽기 때문입니다.
3x3에서 테두리 셀의 경우 수를 따져보면 8가지입니다. 8가지 각각에 대해 대응하는 if문을 작성한다면?
문제에서 판의 크기는 동적으로 바뀝니다. 10x10일 수도 있고, 7x10일 수도 있습니다. 각각의 판 크기가 다를 때 경우의 수는? 그걸 다 처리하려고 if를 작성한다면?
그렇다면 심사문제의 해설에서 제시하는 것처럼 어떤 조건일 때는 나머지 코드는 실행하지 않는 continue를 사용하는 방법이 더 좋습니다.그래도 나는 내 방법으로 풀고 싶다면? Unit 6 디버거 사용하기를 이용해서 각각의 케이스를 추적하며 문제가 발생할 때 변수들의 값이 어떻게 되는지 판단해야 합니다. 정사각형이 아니라 직사각형일 때의 케이스를 처리하지 못하면 심사를 통과하기 어렵습니다.
테두리 경계일 때 그 경계를 벗어나게 됩니다. 다른 셀의 범위를 우연히 참조해서 동작하는 것처럼 보이는 경우도 있습니다. 직사각형 판은 이런 오류를 감춰주는 역할을 하지만, 3x10만 되어도 이런 오류는 반드시 드러납니다.
후 방금 해결했네요.. !!
근데 시험은 통과한다고 떠도 visual studio 출력란에서
'1>c:\project\fairytale\fairytale\fairytale.c(63): warning C4244: '=': 'int'에서 'char'(으)로 변환하면서 데이터가 손실될 수 있습니다.' 라고 뜨는건 상관 없는건가요??
warning이 뜨는 부분은 잠재적으로 버그가 발생할 수 있으므로 발생하지 않게 하는 것이 좋습니다.
int를 char로 변환하는 것은 그리 좋은 전략은 아닙니다.