본문 바로가기

C++ in Windows/Challenges

ICPC 대비 문제 2. 지뢰찾기


문제 2. 지뢰찾기


PC/UVa ID:110102/10189, 인기도: A, 성공률:높음, 레벨: 1


지뢰 찾기를 해본 적있는 독자들이 많을 것이다. 이름은 잘 기억이 안나지만 어떤 운영체제에 이

작고 귀여운 게임이 깔려있다. 지뢰찾기는 M X N 크기의 지뢰밭에서 모든 지뢰의 위치를 찾아내는 

게임이다.


이 게임에서는 각 칸에 인접한 칸에 몇 개의 지뢰가 있는지를 보여준다. 각 칸에는 최대 여덟 개의 

인접한 칸이 있을수 있다. 아래에서 왼쪽에 있는 4X4 지뢰밭에는 지뢰 두개가 있으며 각각은 '*'문

자로 표시되어 있다. 이 지뢰밭을 방금 설명한 힌트 숫자로 표기하면 오른쪽에 있는 것과 같은 필드

가 만들어진다.


*... *100

.... 2210

.*.. 1*10

.... 1110


>> 입력

입력은 임의 개수의 지뢰밭으로 구성된다. 각 지뢰밭의 첫번째 줄에는 각각 행과 열의 개수를 나타내는 두

개의 정수 n과 m(0<n, m<=100)이 들어있다. 그 다음 줄부터는 n개의 줄에 걸쳐서 각 줄마다 정확하게 m

개의 문자가 들어있으며 이는 지뢰밭을 나타낸다.


지뢰가 없는 칸은 '.'으로, 지뢰는 '*'로 표시되며 이때 따옴표는 쓰지 않는다. n=m=0 인 줄은 입력이

끝났음을 나타내는 것이므로 그 줄은 처리하지 않는다.


>> 출력

각 지뢰밭에 대해 Field #x:라고 적혀있는 메시지를 출력한다. 이때 x는 필드번호를 나타내며 1에서 시작

한다. 그 다음 줄부터는 n개의 줄에 걸처서 '.' 문자 대신 그 칸에 인접한 칸에 들어있는 지뢰의 개수를 

출력한다. 각 지뢰밭에 대한 출력 사이에는 반드시 빈 줄이 하나씩 있어야 한다.


>> 입력예

4 4

*...

....

.*..

....

3 5

**...

.....

.*...

0 0 


>> 출력예

Field #1:

*100

2210

1*10

1110


Field #2:

**100

33200

1*100



소스보기
#include <iostream>

using namespace std;

class mine
{
public:
	mine()
	{
		this->cnt = 0;
	}

	~mine()
	{

	}

private:
	char **map;
	int x, y;
	int cnt; 
public:

	void InputSize(int x, int y)
	{
		this->x = x;
		this->y = y;

		this->map = new char*[this->y];

		for (int i = 0 ; i < this->y; i++ )
		{
			this->map[i] = new char[this->x+1];
		}
	}
	
	void InputMap(int row, char* line)
	{
		int i;
		for(i = 0; i < this->x; i++)
		{
			if (line[i] == '*')
				this->map[row][i] = '*';
			else if (line[i] == '.')
				this->map[row][i] = '0';
			else
				this->map[row][i] = '0';
		}

		this->map[row][i] = NULL;
	}

	void CalcMap (void)
	{
		++this->cnt;
		

		for ( int x = 0; x < this->x; x++ )
		{
			for ( int y = 0; y < this->y; y++ )
			{
				if ( this->map[y][x] == '*')
				{
					this->AddCnt(x-1, y-1);
					this->AddCnt(x, y-1);
					this->AddCnt(x+1, y-1);
					this->AddCnt(x+1, y);

					this->AddCnt(x+1, y+1);
					this->AddCnt(x, y+1);
					this->AddCnt(x-1, y+1);
					this->AddCnt(x-1, y);
				}
			}
		}
	}

	void Print(void)
	{
		cout << "Field #" << this->cnt << ":\n";

		for(int i = 0; i < this->y; i++)
		{
			cout << this->map[i] << "\n";
		}
	}

	void MapRelease(void)
	{
		for(int i = 0; i < this->y; i++)
		{
			delete []this->map[i];
		}

		delete []this->map;
	}

private:

	void AddCnt(int x, int y)
	{

		if ( x >= 0 && y >= 0 && x < this->x && y < this->y)
		{
			if( this->map[y][x] != '*' )
				this->map[y][x] += 1;
		}
	}
};

void main (void)
{
	mine p;
	while(true)
	{	
		int x, y;

		cin >> y >> x ;
		
		if ( x == 0 && y == 0 )
			break;
		if ( x == 0 || y == 0 || x > 100 || y > 100 )
			continue;

		p.InputSize( x, y );

		for ( int i = 0 ; i < y; i++ )
		{
			char* line = new char[x+1];
			cin >> line;
			p.InputMap(i, line);

			delete line;
		}

		p.CalcMap();
		p.Print();
		p.MapRelease();
	}
		
}