문제 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();
}
}