본문 바로가기

C언어 강좌

[C언어_12] C언어 문제 풀이 #4

안녕하세요.

 

이번 포스팅에서는 2차원 배열을 이용한 문제를 풀어보려고 합니다.

지난 강좌 Review

swdoodle.tistory.com/16

 

[C언어_11] 2차원 배열과 메모리의 특성

안녕하세요, 이번 포스팅에서는 1차원 배열에 이어서 2차원 배열에 대해 살펴보겠습니다. 또한 2차원 배열은 실제 컴퓨터 메모리공간상에서 어떤 식으로 구현되는지 심층적으로 살펴보겠습니다

swdoodle.tistory.com

지난시간에는 2차원 배열과 메모리의 특성에 대해 알아보았습니다.

 

이번시간에는 2차원 배열을 보다 쉽게 이해할 수 있는 문제를 가져왔습니다.

 

C언어 문제

이번 문제는

 

9x9 크기의 지뢰찾기 게임을 만드는 것입니다.

 

문제 출처 : codeup.kr/problem.php?id=1524

 

지뢰 찾기 1

(r, c) 주변의 지뢰 개수를 출력한다. 만약 (r,c)가 지뢰가 있는 자리이면 -1을 출력한다.

codeup.kr

우리는 값을 입력하여서 지뢰찾기 맵을 만들고

 

좌표를 입력하여 그 주위에 지뢰가 몇 개 있는지 출력하는 프로그램을 만들려고 합니다.

 

 

문제 조건

먼저 값을 다음과 같이 입력합니다.

 

1 0 1 0 0 0 0 0 0

1 0 0 0 1 0 0 0 0

1 0 0 0 1 0 0 1 0

1 0 1 1 1 0 0 0 0

1 0 1 0 1 0 0 0 0

1 0 1 1 1 0 0 1 0

1 0 0 0 1 0 0 0 0

1 0 0 0 1 0 0 1 0

1 0 0 0 1 0 0 0 0

 

여기서 1은 지뢰, 0은 빈칸을 의미합니다.

 

즉 다음과 같이 지뢰가 있다고 가정합시다.

 

 

 

여기서 좌표는 맨 왼쪽 위칸이 ( 0 , 0 ) 이라고 가정하고

 

↓가 X축의 양의 방향, →가 Y축의 양의 방향 이라고 가정합시다.

 

문제 풀이

먼저 위의 지뢰찾기 맵을 2차원 배열을 이용해서 저장해봅시다.

 

#include <stdio.h>
    
void main(){

    int nums[9][9] = {}; //2차원 배열 만들기

	for(int i = 0; i < 9; i++) //X방향
	{
		for(int k = 0; k < 9; k++) //Y방향
		{
			scanf("%d", &nums[i][k]);
		}
	}
}

 

위와 같이 코드를 작성하고 값을 입력하면

num[0][0] = 1 num[0][1] = 0 num[0][2] = 1
num[1][0] = 1 num[1][1] = 0 num[1][2] = 0





 

위와 같이 값이 저장될 것 입니다.

 

 

그리고 우리가 입력하고자 하는 칸의 좌표를 입력받아야겠지요?

 

int X,Y; ////X : X좌표, Y : Y좌표

scanf("%d %d". &X, &Y); ///X Y 형태로 입력
    

위와 같이 코드를 작성하면 될 것입니다.

 

여기서 입력한 값이 ( 5, 5 )이라고 가정합시다.

 

 

그러면 ( 5 , 5 )칸의 주위에는 지뢰가 몇개가 있을까요?

 

주위의 9칸을 살펴보면

 

 

지뢰는 총 3개가 있는 것을 알 수 있습니다.

 

즉 우리가 살펴보아야 할 칸은

 

(4 , 4) (4 , 5) (4 , 6)
(5 , 4) (5 , 5) (5 , 6)
(6 , 4) (6 , 5) (6 , 6)

위와 같이 8칸을 살펴보아야 합니다.

 

그러면 조건문과 반복문을 적절히 활용하면 되겠지요?

 

int count = 0;
	
for(int i = X-1; i <= X+1; i++)
{
	for(int k = Y-1; k <= Y+1; k++)
	{
		if (nums[i][k] == 1) //만약 칸의 값이 1 일경우
			count++;
	}
}

 

위 코드에서는 ( 5, 5 )가 지뢰가 아니라고 가정하였습니다.

 

지뢰찾기 게임을 해보았을 때 지뢰를 밟으면 게임오버가 되지요?

 

입력한 값에 지뢰가 있을 때 GAME OVER!라는 문장을 출력해줍시다.

 

int count = 0;

if(nums[X][Y] == 1)
	printf("GAME OVER!");
else{
	for(int i = X-1; i <= X+1; i++)// X-1 부터 X+1까지
	{
		for(int k = Y-1; k <= Y+1; k++)//  Y-1 부터 Y+1까지
		{
			if (nums[i][k] == 1) //만약 칸의 값이 1 일경우
			count++;
		}
	}
    printf("Mines Found : %d", count);
}

그러면 제대로 작동하는지 확인해 볼까요?

 

아래의 코드를 실행해보세요.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main()
{
	int nums[9][9] = {};
	int X, Y;

	for(int i = 0; i < 9; i++)
	{
		for(int k = 0; k < 9; k++)
		{
			scanf("%d", &nums[i][k]);
		}
	}

	scanf("%d %d", &X, &Y);


	int count = 0;

	if (nums[X][Y] == 1)
		printf("GAME OVER!");
	else {
		for (int i = X - 1; i <= X + 1; i++)
		{
			for (int k = Y - 1; k <= Y + 1; k++)
			{
				if (nums[i][k] == 1) //만약 칸의 값이 1 일경우
					count++;
			}
		}
		printf("Mine Found : %d", count);
	}
}

 

 

제대로 작동하는 것을 확인할 수 있습니다.

 

 

생각해보기

위의 문제는 가장자리를 고려하지 않은 문제입니다.

 

만약 입력한 값이 가장자리에 있는 칸이라면

 

조건문과 반복문이 바뀌어야 합니다.

 

이 경우를 추가해서 한번 프로그램을 만들어 보세요.

 

| 마무리

이번 시간에는 배열을 활용한 문제를 풀어보았습니다.

 

이 문제를 통해서 배열을 좀 더 쉽게 이해하셨으면 좋겠습니다.

 

감사합니다.