일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 삼성
- 온라인 저지 구축
- 구축
- SW Expert Academy
- hustoj
- STL
- 역테
- 저지시스템구축
- 모의 SW 역량테스트
- 모의 SW역량테스트
- SWIFT
- xcode
- SW역량테스트
- 삼성기출
- a형
- IOS
- 백준
- c++
- SWEA
- oj
- 7576
- 개발
- 온라인저지시스템구축
- 소스코드
- BOJ
- 알고리즘
- oj구축
- 역량테스트
- 비트마스킹
- 풀이
Archives
- Today
- Total
꾸르꾸르
[BOJ] 14499번 주사위 굴리기 풀이 (C++) 본문
2017.10.6에 작성된 글 입니다.
문제링크
https://www.acmicpc.net/problem/14499
풀이방법
주사위 전개도가 주어지는데 저걸 준 이유는
배열에 차례대로 넣어서 사용하세요 라고 친절하게 더 쉽게 접근할수있도록 해준것임.
굳이 저거 무시하고 전개도를 새로 만들어서 해도 무방함.
푸는 방법은 먼저 dice[6] 배열에 각각의 주사위 면에 써있는 숫자를 저장함
그리고나서 주사위를 굴릴때 주사위 자체를 굴리는 것이 아니라 주사위는 고정되어있고 숫자가 이동한다고 생각하면 됨
그래서 위에 코드 소스코드를 보면 임시 주사위 배열을 만들어서 거기에 숫자가 이동한 값을 써주는 것임
그리고 그걸 지금 주사위라고 표시해주는것임
이런식으로 풀어제끼고 바닥면 체크해주고 윗면출력해주면 풀림.
나머지는 소스코드와 주석 참고
소스코드
-소스코드1
#include <iostream>
using namespace std;
enum { TOP = 0, EAST, WEST, NORTH, SOUTH, BOTTOM };
int map[20][20];//좌표배열
int a[1000]; //이동명령배열
int dice[6]; //주사위배열
// 윗 동 서 북 남 밑
// 0 1 2 3 4 5
int tmp_dice[6];
void Init() //맵, 이동명령 초기화
{
for (int i = 0; i < 20; i++)
for (int j = 0; j < 20; j++)
map[i][j] = 0;
for (int i = 0; i < 1000; i++)
a[i] = 0;
for (int i = 0; i < 6; i++) {
dice[i] = 0;
tmp_dice[i] = 0;
}
}
void Copy() //임시 다이스 복사
{
for (int i = 0; i < 6; i++)
tmp_dice[i] = dice[i];
}
void Check(int cur_x, int cur_y, int x_size, int y_size, int K)
{
for (int i = 0; i < K; i++) {
switch (a[i]) {
case(EAST): //동 -> 밑 , 밑->서, 서->윗, 윗 ->동
if (cur_y + 1 < y_size) {
/*다이스 이동*/
dice[BOTTOM] = tmp_dice[EAST];
dice[WEST] = tmp_dice[BOTTOM];
dice[TOP] = tmp_dice[WEST];
dice[EAST] = tmp_dice[TOP];
cur_y++;
/*다이스이동*/
if (map[cur_x][cur_y] == 0) //칸이 0이면
map[cur_x][cur_y] = dice[BOTTOM]; //주사위 바닥을 칸에 대입
else {
dice[BOTTOM] = map[cur_x][cur_y]; //아니면 칸의 값을 주사위 바닥으로 복사
map[cur_x][cur_y] = 0;
}
cout << dice[TOP] << endl;
Copy(); //주사위 복사
}
break;
case(WEST): //서->밑, 밑->동, 동->윗, 윗->서
if (cur_y - 1 >= 0) {
dice[BOTTOM] = tmp_dice[WEST];
dice[EAST] = tmp_dice[BOTTOM];
dice[TOP] = tmp_dice[EAST];
dice[WEST] = tmp_dice[TOP];
cur_y--;
if (map[cur_x][cur_y] == 0) //칸이 0이면
map[cur_x][cur_y] = dice[BOTTOM]; //주사위 바닥을 칸에 대입
else {
dice[BOTTOM] = map[cur_x][cur_y]; //아니면 칸의 값을 주사위 바닥으로 복사
map[cur_x][cur_y] = 0;
}
cout << dice[TOP] << endl;
Copy(); //주사위 복사
}
break;
case(NORTH): //북->밑, 밑->남, 남->윗, 윗->북
if (cur_x - 1 >= 0) {
dice[BOTTOM] = tmp_dice[NORTH];
dice[SOUTH] = tmp_dice[BOTTOM];
dice[TOP] = tmp_dice[SOUTH];
dice[NORTH] = tmp_dice[TOP];
cur_x--;
if (map[cur_x][cur_y] == 0) //칸이 0이면
map[cur_x][cur_y] = dice[BOTTOM]; //주사위 바닥을 칸에 대입
else {
dice[BOTTOM] = map[cur_x][cur_y]; //아니면 칸의 값을 주사위 바닥으로 복사
map[cur_x][cur_y] = 0;
}
cout << dice[TOP] << endl;
Copy(); //주사위 복사
}
break;
case(SOUTH): //남->밑, 밑->북, 북->윗, 윗->남
if (cur_x + 1 < x_size) {
dice[BOTTOM] = tmp_dice[SOUTH];
dice[NORTH] = tmp_dice[BOTTOM];
dice[TOP] = tmp_dice[NORTH];
dice[SOUTH] = tmp_dice[TOP];
cur_x++;
if (map[cur_x][cur_y] == 0) //칸이 0이면
map[cur_x][cur_y] = dice[BOTTOM]; //주사위 바닥을 칸에 대입
else {
dice[BOTTOM] = map[cur_x][cur_y]; //아니면 칸의 값을 주사위 바닥으로 복사
map[cur_x][cur_y] = 0;
}
cout << dice[TOP] << endl;
Copy(); //주사위 복사
}
break;
}
}
}
int main()
{
int N, M, K;
int x, y;
cin >> N >> M >> x >> y >> K;
Init(); //초기화
for (int i = 0; i < N; i++) //좌표 입력
for (int j = 0; j < M; j++)
cin >> map[i][j];
for (int i = 0; i < K; i++) //이동명령 입력
cin >> a[i];
Check(x, y, N, M, K);
return 0;
}
-소스코드2 (큐 이용)
#include <iostream>
#include <queue>
using namespace std;
enum DIR { EAST = 0, WEST = 1, NORTH = 2, SOUTH = 3 }; //방향
enum DICE { UP = 0, BACK = 1, RIGHT = 2, LEFT = 3, FRONT = 4, BOTTOM = 5 }; //주사위 면 위치
int N, M, K; //N M K
int map[20][20]; //맵
queue < int > q; //명령 넣어놓을 큐
int dice[6]; //주사위 각 면에 쓰인 수 저장
int tmp_dice[6]; //임시 주사위배열
int dice_x, dice_y; //현재주사위의 x,y위치
int dx[] = { 0,0,-1,1 };//동 서 북 남
int dy[] = { 1,-1,0,0 };
void copy_tmp_dice() //tmp -> dice로 복사
{
for (int i = 0; i < 6; i++)
dice[i] = tmp_dice[i];
}
void copy_dice_tmp() //dice -> tmp로 복사
{
for (int i = 0; i < 6; i++)
tmp_dice[i] = dice[i];
}
void Init() //초기화
{
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
map[i][j] = -1;
for (int i = 0; i < 6; i++) {
dice[i] = 0;
tmp_dice[i] = 0;
}
}
void solve(int order) //명령을 인자로 받고
{
copy_dice_tmp(); //현재 주사위를 임시배열에 저장하고
int new_x = dice_x + dx[order]; //주사위의 다음 이동좌표를 새로운 좌표를 설정
int new_y = dice_y + dy[order];
if (0 <= new_x&&new_x < N && 0 <= new_y&&new_y < M) { //그 새로운 좌표가 범위안에있으면
switch (order) {
case EAST: //동쪽이면 동쪽으로 굴림
tmp_dice[BOTTOM] = dice[RIGHT];
tmp_dice[RIGHT] = dice[UP];
tmp_dice[UP] = dice[LEFT];
tmp_dice[LEFT] = dice[BOTTOM];
break;
case WEST: //서쪽이면 서쪽으로 굴림
tmp_dice[BOTTOM] = dice[LEFT];
tmp_dice[RIGHT] = dice[BOTTOM];
tmp_dice[UP] = dice[RIGHT];
tmp_dice[LEFT] = dice[UP];
break;
case NORTH: //북쪽이면 북쪽으로 굴림
tmp_dice[BOTTOM] = dice[BACK];
tmp_dice[FRONT] = dice[BOTTOM];
tmp_dice[UP] = dice[FRONT];
tmp_dice[BACK] = dice[UP];
break;
case SOUTH: //남쪽이면 남쪽으로 굴림
tmp_dice[FRONT] = dice[UP];
tmp_dice[BOTTOM] = dice[FRONT];
tmp_dice[BACK] = dice[BOTTOM];
tmp_dice[UP] = dice[BACK];
break;
}
copy_tmp_dice();//tmp_dice에 굴린후의 주사위 상태가 저장됬으니까 dice로 복사시켜줌
if (map[new_x][new_y] == 0) //새로운 좌표의 값이 0이면
map[new_x][new_y] = dice[BOTTOM]; //바닥면을 맵에 복사
else { //0이아니면
dice[BOTTOM] = map[new_x][new_y]; //맵에 값을 주사위에 복사
map[new_x][new_y] = 0; //복사후 맵의 값은 0으로
}
dice_x = new_x; //주사위 위치를 이동한 좌표로 설정
dice_y = new_y;
cout << dice[UP] << endl; //윗면 출력
}
}
int main()
{
cin >> N >> M >> dice_x >> dice_y >> K; //입력받고
Init(); //초기화
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
cin >> map[i][j]; //맵 입력받기
for (int i = 0; i < K; i++) {
int command;
cin >> command;
q.push(command - 1); //명령을 큐에 저장
}
while (!q.empty()) { //큐 빌때까지 돌림
int order = q.front(); //order에 저장해놓고
q.pop(); //큐빼줌
solve(order); //해당 명령 수행
}
return 0;
}
참고
이번에도 새로 풀어봄. 사실 1과 2가 거의 같은 코드인데 배열에 명령을 넣냐 큐에 넣냐의 차이 정도 인듯..
예전에는 큐 잘안썼는데 요새는 큐에 노예가 된거마냥 겁나 많이 쓰는중ㅋㅋㅋㅋㅋ 넘 좋음..
그나저나 다시 풀때 자꾸 틀리길래 뭔가했더니 밑면을 복사하고난담에 지도에 0으로 만들어주지를 않아서 계속 틀렸음 -_-;;
시작하자마자 틀리길래뭔가했네.. 문제 대충읽지말자 제발제발제발 반성하자 나넘아 !! ㅠㅠ
'코딩, 알고리즘, 문제풀이 > BOJ 백준' 카테고리의 다른 글
[BOJ] 14503번 로봇 청소기 문제풀이 (C++) (0) | 2019.05.17 |
---|---|
[BOJ] 14502번 연구소 문제풀이 (C++) (0) | 2019.05.16 |
[BOJ] 13458번 시험감독 풀이 (C++) (0) | 2019.05.13 |
[BOJ] 14500번 테트로미노 문제풀이 (C++) (0) | 2019.05.12 |
[BOJ] 14501번 퇴사 문제풀이 (C++) (0) | 2019.05.11 |
Comments