오늘 풀어볼 문제는
ascode 1003번 차차 퀘스트이다!
http://www.ascode.org/problem.php?id=1003
ascode.org discuss3
문제 설명 gugugugu는 이번에 새로 나온 게임인 차차 퀘스트를 플레이하고 있다. 대망의 첫 던전에 입장한 gugugugu. 하지만 매번 몬스터의 수를 몰라 죽고 마는데... gugugugu를 위해 던전 안에 있는 몬스터의 수를 세어 주는 프로그램을 작성하자. 입력 설명 첫 줄에 테스트 케이스의 수 T가 입력된다. 다음 줄부터 T만큼, 던전 맵의 사이즈 W, H (1 <= W, H <= 32)와 gugugugu의 행동 범위 R (1 <= R <= 5)
www.ascode.org
문제 분석
조건 정리
1. 너비 W, 높이 H, 행동범위 R이 차례로 입력된다. (1 <= W, H <= 32 / 1 <= R <= 5)
2. W * H 크기의 맵이 입력된다.
3. 몬스터 : 대문자 A~Z, 빈공간 : #, 플레이어 : @
4. 존재하는 몬스터의 수를 출력하고 플레이어 R만큼의 주변에 몬스터가 몇 마리 있는지 출력한다.
문제 해결
1. 입력을 받는 동시에 몬스터 수를 헤아린다.
2. 몬스터 수를 헤아리는 int 배열을 만든다.
3. switch문으로 빈공간, 플레이어, 몬스터를 판독한다.
4. 2차원 배열을 만들어 몬스터가 존재할 때마다 값을 넣는다.
5. 존재하는 몬스터의 수는 몬스터의 수가 저장되어있는 배열의 값이 0 이상일 때 출력하도록 해 표기한다.
6. 주변의 몬스터는 (플레이어의 위치 - R 값) 부터 (플레이어의 위치 + R값) 까지 탐색하여 헤아린 후 표기한다.
※ 사소한 실수 포인트 ※
1. 주변의 몬스터가 없을 때에는 "Monsters Nearby" 수치를 출력하지 않는다.
2. 각 결과 사이에는 줄바꿈이 한 줄 더 있다.
나도 이 두 개 때문에 틀렸당ㅠㅠ
코드작성
1. 입력 및 변수 생성
int main() {
int testCase;
scanf("%d", &testCase);
while (testCase--) {
char map[33][33] = { 0 };
int width, height, round;
int posX = 0, posY = 0;
int monster[26] = { 0 }, near = 0;
scanf("%d %d %d", &width, &height, &round);
}
}
test case가 있을 때 마다 내가 주로 쓰는 방법으로 while문을 작성했다.
char map[][] : 입력받은 맵을 저장하는 곳이다. 문자이기 때문에 null값 위치를 포함해 33개를 지정했다.
int width, height, round : 맵의 가로, 세로, 탐색할 주변의 크기
int posX, posY : 플레이어의 위치를 저장할 것이다.
int monster[] : 종류에 따른 몬스터 갯수를 저장하는 곳이다. 몬스터는 알파벳 범위이기 때문에 26개를 지정했다.
int near : 주변에 있는 몬스터 수를 헤아리기 위한 용도이다.
2. 맵 입력 및 몬스터 판독
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
char cur;
scanf(" %c", &cur);
switch (cur) {
// 빈공간 체크
case '#' :
break;
// 플레이어 체크
case '@' :
posX = j;
posY = i;
break;
// 몬스터 체크
default:
monster[cur - 'A']++;
map[i][j] = 1;
break;
}
}
}
2차원 배열은 2중 for문을 이용하여 입력받는 것이 흔한 형태이다.
첫번째 for문을 통해 얼만큼의 높이를 판독 할 것인지
두번째 for문을 통해 얼만큼의 너비를 판독 할 것인지 를 결정한다.
현재 보고 있는 값이 어떤 것인지를 저장하는 cur이라는 char 변수를 만들었다.
switch case 문을 통해 #(빈공간), @(플레이어), A~Z(몬스터) 여부를 판단했다.
입력에서 #,@를 제외하면 모두 몬스터이기 때문에 default값으로 몬스터임을 확인했다.
빈공간(#)인 경우 : 아무것도 하지 않고 넘어갔다.
플레이어(@)인 경우 : 현재의 위치 posX, posY를 저장하고 넘어갔다.
몬스터(A~Z)인 경우 :
cur - 'A'라는 아스키 코드 값을 이용한 인덱스 파악을 했다.
ex) A인 경우에는 0번째 인덱스의 값이 증가, D인 경우 3번째 인덱스의 값이 증가.
map에 몬스터가 있었다는 표시로 값을 1로 매긴다.
3. 근처 몬스터 탐색
for (int i = posY-round; i <= posY + round; i++) {
for (int j = posX - round; j <= posX + round; j++) {
if (map[i][j]) {
near++;
}
}
}
근방의 몬스터를 탐색할 것이다.
R : round
posX : 플레이어의 X좌표
posY : 플레이어의 Y좌표
위의 이미지를 통해 알 수 있듯이 탐색범위를 지정가능하다. X축 Y축 모두 round값 만큼 더 탐색하면 되는 것이다.
X탐색 시작 종료 : (posX - round)부터 (posX +round)와 같아질 때까지
X탐색 시작 종료 : (posY - round)부터 (posY +round)와 같아질 때까지
이 때 주어지는 round값은 map범위 이내이므로 맵을 벗어나는 것은 염려하지 않아도 된다.
탐색을 하면서 값이 '1'이면 if문이 통과가 되고 근처 몬스터 수를 증가시켜준다.
4. 존재하는 몬스터 수 출력하기
for (int i = 0; i < 26; i++) {
if (monster[i]) {
printf("%c %d\n", 'A' + i, monster[i]);
}
}
앞서 말했듯이 존재하는 몬스터의 수는 알파벳 갯수와 같기 때문에 26이다.
만약에 배열에 저장되어있는 값이 0이 아니게 되면 if문이 통과할 것이고
아스키 코드 값을 이용해 올바른 문자를 출력하게 된다.
5. 주변 몬스터 수 출력하기
if (near) {
printf("Monsters Nearby %d\n", near);
}
printf("\n");
주변에 "몬스터가 있다면" 해당 문구를 출력하는 것이었다.
따라서 near값이 0이 아닐 때만 저 문구를 출력하도록 if문을 작성했다.
그 후 각 출력은 줄넘김이 한 줄 더 있으므로 엔터를 한 번 더 쳐주는 것으로 코드를 마무리 짓는다.
전체 코드
#include <stdio.h>
#pragma warning (disable : 4996)
int main() {
int testCase;
scanf("%d", &testCase);
while (testCase--) {
char map[33][33] = { 0 };
int width, height, round;
int posX = 0, posY = 0;
int monster[26] = { 0 }, near = 0;
scanf("%d %d %d", &width, &height, &round);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
char cur;
scanf(" %c", &cur);
switch (cur) {
case '#' :
break;
case '@' :
posX = j;
posY = i;
break;
default:
monster[cur - 'A']++;
map[i][j] = 1;
break;
}
}
}
for (int i = posY-round; i <= posY + round; i++) {
for (int j = posX - round; j <= posX + round; j++) {
if (map[i][j]) {
near++;
}
}
}
for (int i = 0; i < 26; i++) {
if (monster[i]) {
printf("%c %d\n", 'A' + i, monster[i]);
}
}
if (near) {
printf("Monsters Nearby %d\n", near);
}
printf("\n");
}
}
의문점이 생긴다면 댓글질문!
풀다 어려웠던 문제도 적어주면 좋겠지만
여기 오는 사람이 없겠지...ㅠㅠ
'ascode 문제풀이' 카테고리의 다른 글
[ascode 문제풀이] 1006: 문자열중 문자의 갯수 구하기 (0) | 2020.04.08 |
---|---|
[ascode 문제풀이] 1004: 시분할 연습 #1 (0) | 2020.03.26 |
[ascode 문제풀이] 1001: 나는 차차를 싫어해! (0) | 2020.03.03 |