문제보기
이번 문제도 한 번에 AC를 받지는 못했다. 3n+1 문제에 이어 또 한번의 좌절을 겪고 있을 때 의외로 간단히 해결책을 알아냈다. 단지 배열의 크기를 조금 더 크게 하는 것으로 문제를 해결했다. 결국 Online Judge가 너무 엄격하다고 밖에 생각이 안 된다.
소스
소스에서 #define MAX 100으로 처음 했더니 WA를 받았다. 정확한 이유는 글쎄-_-;(아래 글상자 참고) 구글에서 검색하다가 이 페이지에서 다음과 같은 내용을 발견하고 소스를 수정했다.
한 가지 의외였던 것은 배열에서 '*'를 검사한 후 주변부 8개의 값을 1씩 더해줄 때 경계에 있는지 확인하지 않아도 프로그램이 잘 돌아간다는 것이다. 배열 인덱스가 음수가 되면 에러가 날 줄 알았는데 컴파일러에서 알아서 처리하는 모양이다.
이제 겨우 두 문제를 풀어보았는데 아직 UVa 문제가 익숙하지 않아서인지 때로는 문제의 조건이 부족하다는 생각이 든다. 예를 들어 이 문제의 경우 n과 m값 중에서 둘 중에 하나만 0이 입력될 경우에는 어떻게 할 것인지, 혹은 100 이상이 될 경우에는 어떻게 할 것인지에 대한 조건이 없다. 문제에 0 < n, m <= 100 란 조건이 있는데 입력되는 값은 이 범위를 벗어나지 않는다는 가정을 했다고 생각하는 수 밖에 없는 듯.
C문법만 알고 C++문법은 거의 잘 몰라서 소스를 작성하는 것도 고민이 된다. C++에 관한 책을 좀 찾아봐야 할 것 같다.
이번 문제도 한 번에 AC를 받지는 못했다. 3n+1 문제에 이어 또 한번의 좌절을 겪고 있을 때 의외로 간단히 해결책을 알아냈다. 단지 배열의 크기를 조금 더 크게 하는 것으로 문제를 해결했다. 결국 Online Judge가 너무 엄격하다고 밖에 생각이 안 된다.
소스
#include "iostream"
#include "stdio.h"
#define MAX 101
using namespace std;
int main()
{
int i, j; // 지뢰밭의 크기(i, j)
int m, n; // *를 중심으로 주변부 8개의 값을 1씩 더하기 위해 사용(m, n)
int l, c; // 지뢰밭 배열을 초기화 하고 입출력을 위한 변수
int fieldnum=1; // 필드번호
char line[MAX]; // 지뢰밭을 입력받을 때 사용하는 배열
char field[MAX][MAX]; // 지뢰밭 배열
while(i || j)
{
// 두 정수를 입력받는다.
cin >> i >> j;
if(i==0 || j==0 || i >100 || j>100)
break;
// field 배열을 초기화
for(l=0; l<i; l++)
{
for(c=0; c<j; c++)
{
field[l][c]='0';
}
}
// 한 줄씩 입력받고, 입력 받을 때마다 값을 읽고 field 배열에 반영
for(l=0; l<i; l++)
{
cin >> line;
for(c=0; c<j; c++)
{
if(line[c] == '*')
{
field[l][c] = '*'; // mine을 필드에 표시
// 주위 8개의 값을 1씩 더함
for(m=0; m<3; m++)
{
for(n=0; n<3; n++)
{
if(field[l-1+m][c-1+n]!='*') // 필드의 값이 '*'이 아닐 경우에만 1을 더함
field[l-1+m][c-1+n] += 1;
}
}
}
}
}
// 출력
if (fieldnum >1 ) cout << endl;
cout << "Field #" << fieldnum << ":" << endl;
for(l=0; l<i; l++)
{
for(c=0; c<j; c++)
{
cout << field[l][c];
}
cout << endl;
}
fieldnum++;
} // end of while
return 0;
}
소스에서 #define MAX 100으로 처음 했더니 WA를 받았다. 정확한 이유는 글쎄-_-;(아래 글상자 참고) 구글에서 검색하다가 이 페이지에서 다음과 같은 내용을 발견하고 소스를 수정했다.
Increase your array (out) size to 101.
On a 100x100 board, you sometimes attempt to increase out[x][100], which in memory is the same as out[x+1][0] and is thus incrementing something you don't want to.
Also, you can make the array size 102 and start everything at 1, so you don't have to worry about indexes going below 0 as well, and eliminate the bounds checking altogether.
Alternatively, you can just fix your bounds checking, but the above recommendation is probably quicker.
문자열 변수의 경우 변수 선언시 하나의 메모리 공간이 널 종료자(null terminator)를 위해 할당된다.
char VARNAME[N];
여기서 N은 변수가 가질 수 있는 문자의 최대 개수이고 []안의 숫자는 반드시 실제로 정하려는 문자 개수보다 하나만큼 커야 한다. \O(null terminator) 문자를 저장할 공간을 필요로 하기 때문이다.
내가 처음 line[MAX]에서 MAX를 100으로 생각한건 line[0]부터 line[100]까지 총 101개의 공간이 생성된다고 생각했기 때문이다. 오랜만에 C를 다시 접하다 보니 이런 문제도 생기는 것 같다. C문법 공부를 다시 해야 할듯하다.(2009. 7. 29. 추가)
char VARNAME[N];
여기서 N은 변수가 가질 수 있는 문자의 최대 개수이고 []안의 숫자는 반드시 실제로 정하려는 문자 개수보다 하나만큼 커야 한다. \O(null terminator) 문자를 저장할 공간을 필요로 하기 때문이다.
내가 처음 line[MAX]에서 MAX를 100으로 생각한건 line[0]부터 line[100]까지 총 101개의 공간이 생성된다고 생각했기 때문이다. 오랜만에 C를 다시 접하다 보니 이런 문제도 생기는 것 같다. C문법 공부를 다시 해야 할듯하다.(2009. 7. 29. 추가)
한 가지 의외였던 것은 배열에서 '*'를 검사한 후 주변부 8개의 값을 1씩 더해줄 때 경계에 있는지 확인하지 않아도 프로그램이 잘 돌아간다는 것이다. 배열 인덱스가 음수가 되면 에러가 날 줄 알았는데 컴파일러에서 알아서 처리하는 모양이다.
이제 겨우 두 문제를 풀어보았는데 아직 UVa 문제가 익숙하지 않아서인지 때로는 문제의 조건이 부족하다는 생각이 든다. 예를 들어 이 문제의 경우 n과 m값 중에서 둘 중에 하나만 0이 입력될 경우에는 어떻게 할 것인지, 혹은 100 이상이 될 경우에는 어떻게 할 것인지에 대한 조건이 없다. 문제에 0 < n, m <= 100 란 조건이 있는데 입력되는 값은 이 범위를 벗어나지 않는다는 가정을 했다고 생각하는 수 밖에 없는 듯.
C문법만 알고 C++문법은 거의 잘 몰라서 소스를 작성하는 것도 고민이 된다. C++에 관한 책을 좀 찾아봐야 할 것 같다.
'ACM ICPC/정보올림피아드' 카테고리의 다른 글
| [UVa 10189] Minesweeper(지뢰 찾기) (0) | 2009/07/28 |
|---|---|
| [UVa 100] 해결되지 않는 3n+1 문제 (4) | 2009/07/28 |
| ACM ICPC/정보올림피아드 카테고리 개설 (0) | 2009/07/28 |





댓글을 달아 주세요