Problem Solving/SWEA
SWEA 5650번: [모의 SW 역량테스트] 핀볼 게임
이진2
2020. 5. 11. 01:35
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRF8s6ezEDFAUo
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
핀볼게임은 단순한 완전탐색 문제!!
빈칸은 0, 맵 중간의 블록들은 1~5, 웜홀은 1쌍마다 6~10의 번호를 가진다
핀볼이 움직이면서 벽 혹은 블록에 부딪힐 때마다 점수를 얻을 때, 최대 점수를 획득 가능한 경우를 구하는 문제
이 문제에서는 벽은 5번 블록으로 정해서 벽과 블록의 충돌처리를 동일하게 해주었다
각각의 블록은 입력 인덱스와 출력 인덱스를 전처리 해주었다
ex. block[k][i] = j 일 경우 👉 k번 블록에 i 방향으로 부딪히면, 방향을 j로 바꾼다
충돌 알고리즘은 다음과 같다
소스코드:
#include <cstdio>
#include <cstring>
typedef struct {
int x, y;
}point;
int tc,ans,n,map[105][105];
int dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
//우,하,좌,상
int block[6][4] = {
{0,0,0,0},
{2,0,3,1},
{2,3,1,0},
{1,3,0,2},
{3,2,0,1},
{2,3,0,1}
};
void move(point s, int dir) {
point cur = s;
int sum = 0;
do{
cur.x += dx[dir], cur.y += dy[dir]; //이동
int k = map[cur.y][cur.x];
if (!k)continue; //비엇다면
else if (k == -1)
break;
else if (k <= 5) {
sum++;
dir = block[k][dir];
}
else if (k <= 10) {
bool check=0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) //다른 웜홀 탐색
if (map[i][j] == k && (cur.x != j || cur.y != i)) {
cur.x = j, cur.y = i;
check = 1;
break;
}
if (check)break;
}
}
} while ((cur.x != s.x || cur.y != s.y) //시작 위치랑 블랙홀이 아닐 때 까지
&& map[cur.y][cur.x] != -1);
if (sum > ans)ans = sum;
}
int main() {
scanf("%d", &tc);
for (int T = 1; T <= tc; T++) {
ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &map[i][j]);
for (int i = 1; i <= n; i++) {
map[0][i] = map[n + 1][i] = map[i][0] = map[i][n + 1] = 5;
} //벽을 5번 블록으로 처리
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++){
if (map[i][j])continue;
for (int k = 0; k < 4; k++)
move({ j,i }, k);
}
printf("#%d %d\n",T, ans);
memset(map, 0, sizeof(map));
}
return 0;
}
비교적 간단한 문제 😉
+
이제 문제정의랑 알고리즘 설계는 잘 하는데 예외처리 좀 젭알 잘 하자 😭