문제
https://www.acmicpc.net/problem/23288
설명
main 함수는 다음과 같다.
문제에서의 설명과 같이 다음과 같은 순서로 코드를 작성하였다. 이동 -> 점수 -> 방향결정
- 주사위가 이동 방향으로 한 칸 굴러간다. 만약, 이동 방향에 칸이 없다면, 이동 방향을 반대로 한 다음 한 칸 굴러간다.
- 주사위가 도착한 칸 (x, y)에 대한 점수를 획득한다.
- 주사위의 아랫면에 있는 정수 A와 주사위가 있는 칸 (x, y)에 있는 정수 B를 비교해 이동 방향을 결정한다.
- A > B인 경우 이동 방향을 90도 시계 방향으로 회전시킨다.
- A < B인 경우 이동 방향을 90도 반시계 방향으로 회전시킨다.
- A = B인 경우 이동 방향에 변화는 없다.
int main()
{
cin >> N >> M >> K;
reset();
for(int i = 1; i<= N; i++)
{
for(int j = 1; j<=M; j++)
{
cin >> map[i][j];
}
}
x = 1; y = 1;
moveDir = 0;
for(int i = 0; i<K; i++)
{
// 이동
//cout << "moveDir is: "<< moveDir << endl;
//cout << "x: "<<x<<", y: "<<y<<endl;
if((x+dir[moveDir][0] > N || x+dir[moveDir][0] < 1) || (y+dir[moveDir][1] > M || y+dir[moveDir][1] < 1))
{
if(moveDir < 2)
moveDir+=2;
else
moveDir-=2;
//cout << "change dir"<<endl;
}
moveDice(moveDir);
x += dir[moveDir][0];
y += dir[moveDir][1];
// 점수
B = map[x][y];
C = 1;
reset();
DFS(x, y);
//cout << B*C <<endl;
result += B * C;
// 다음 이동 방향
A = dice[5];
if(A>B)
{
if(moveDir != 3)
moveDir += 1;
else
moveDir = 0;
}
if(A<B)
{
if(moveDir != 0)
moveDir -= 1;
else
moveDir = 3;
}
}
cout << result << '\n';
}
이동할때 사용한 함수는 다음과 같다. 주사위의 전개도를 dice라는 배열에 저장하여 굴리는 방향대로 위치를 바꿔주었다.
void moveDice(int dir)
{
int tmp;
if(dir == 0)
{
tmp = dice[3];
dice[3] = dice[2];
dice[2] = dice[1];
dice[1] = dice[5];
dice[5] = tmp;
}
else if(dir == 1)
{
tmp = dice[5];
dice[5] = dice[4];
dice[4] = dice[2];
dice[2] = dice[0];
dice[0] = tmp;
}
else if(dir == 2)
{
tmp = dice[1];
dice[1] = dice[2];
dice[2] = dice[3];
dice[3] = dice[5];
dice[5] = tmp;
}
else
{
tmp = dice[0];
dice[0] = dice[2];
dice[2] = dice[4];
dice[4] = dice[5];
dice[5] = tmp;
}
}
점수를 계산할 때에는 DFS함수를 사용했다.
void DFS(int x, int y)
{
visited[x][y] = true;
for(int i = 0; i<4; i++)
{
int nx = x+dir[i][0];
int ny = y+dir[i][1];
if(( nx <= N && nx > 0) && (ny <= M && ny > 0))
{
if(map[nx][ny] == B && !visited[nx][ny])
{
visited[nx][ny] = 1;
C += 1;
DFS(nx, ny);
}
}
}
}
전체 코드
#include <iostream>
#include <vector>
using namespace std;
int map[21][21];
bool visited[21][21];
int N, M, K;
int result = 0;
int x, y;
int dice[6] = {2,4,1,3,5,6};
int dir[4][2] ={{0,1}, {1,0}, {0,-1}, {-1,0}};
int moveDir;
int A,B,C;
void DFS(int x, int y);
void moveDice(int dir);
void reset();
int main()
{
cin >> N >> M >> K;
reset();
for(int i = 1; i<= N; i++)
{
for(int j = 1; j<=M; j++)
{
cin >> map[i][j];
}
}
x = 1; y = 1;
moveDir = 0;
for(int i = 0; i<K; i++)
{
// 이동
if((x+dir[moveDir][0] > N || x+dir[moveDir][0] < 1) || (y+dir[moveDir][1] > M || y+dir[moveDir][1] < 1))
{
if(moveDir < 2)
moveDir+=2;
else
moveDir-=2;
}
moveDice(moveDir);
x += dir[moveDir][0];
y += dir[moveDir][1];
// 점수
B = map[x][y];
C = 1;
reset();
DFS(x, y);
result += B * C;
// 다음 이동 방향
A = dice[5];
if(A>B)
{
if(moveDir != 3)
moveDir += 1;
else
moveDir = 0;
}
if(A<B)
{
if(moveDir != 0)
moveDir -= 1;
else
moveDir = 3;
}
}
cout << result << '\n';
}
void moveDice(int dir)
{
int tmp;
if(dir == 0)
{
tmp = dice[3];
dice[3] = dice[2];
dice[2] = dice[1];
dice[1] = dice[5];
dice[5] = tmp;
}
else if(dir == 1)
{
tmp = dice[5];
dice[5] = dice[4];
dice[4] = dice[2];
dice[2] = dice[0];
dice[0] = tmp;
}
else if(dir == 2)
{
tmp = dice[1];
dice[1] = dice[2];
dice[2] = dice[3];
dice[3] = dice[5];
dice[5] = tmp;
}
else
{
tmp = dice[0];
dice[0] = dice[2];
dice[2] = dice[4];
dice[4] = dice[5];
dice[5] = tmp;
}
}
void reset()
{
for(int i = 1; i<= N; i++)
{
for(int j = 1; j<= M; j++)
visited[i][j] = false;
}
}
void DFS(int x, int y)
{
visited[x][y] = true;
for(int i = 0; i<4; i++)
{
int nx = x+dir[i][0];
int ny = y+dir[i][1];
if(( nx <= N && nx > 0) && (ny <= M && ny > 0))
{
if(map[nx][ny] == B && !visited[nx][ny])
{
visited[nx][ny] = 1;
C += 1;
DFS(nx, ny);
}
}
}
}
반응형
'알고리즘 문제 > C++' 카테고리의 다른 글
[백준] 20057번: 마법사 상어와 토네이도 - C++ (1) | 2022.09.21 |
---|---|
[백준] 14567번 : 선수과목 - C++ (0) | 2022.05.04 |
[백준] 23061번 : 백남이의 여행 준비 - C++ (0) | 2022.04.26 |
[백준] 23057번 : 도전 숫자왕 - C++ (0) | 2022.04.26 |
[백준] 1181번: 단어정렬 - C++ (0) | 2022.03.31 |