본문 바로가기

Algorithm/TIP

[C++] 방향,이동 관련 문제

728x90

 

 

→←↑↓ 로 이동해야하는 문제들이 있다.

이런 경우 정석인 방법이 있다고 한다!

 

방향 전환은 

지금 머리가 향하는 방향 / 어디로 방향을 틀 것인가 

두가지로 결정된다.

 

이를 표로 정리하면 다음과 같은 관계를 가진다. 

현재 머리 방향 / 입력으로 들어온 값 L R D
TOP↑
DOWN↓ 
LEFT← ↓ 
RIGHT→ ↓ 

 

 

이를 코드로 표현하면 다음과 같이 표현할 수 있다.

//{x축 이동, y축 이동}
ii dir[4] = {{0,  1},  //우 [head = 0]
             {-1, 0},  //상 [head = 1]
             {0,  -1}, //좌 [head = 2]
             {1,  0}}; //하 [head = 3]
          
          
head = 0; //현재 방향 dir[head]

if (input == 'L')
	head = (head + 1) % 4;
else if (input == 'D')
	head = (head + 2) % 4;
else if(input == 'R')
	head = (head + 3) % 4;



x = x + dir[head].first;
y = y + dir[head].second;

 

또한 바라보고있는 방향과 이동해야하는 방향이 다른 경우에는 이런식으로 해결 할 수 있다

예제) 

북:0 동:1 남:2 서:3 -> 이와같이 이미 고정되어 있어서 상하좌우 이동을 이렇게만 구현해야함

//북 동 남 서 -> 0 1 2 3 으로 지정되어 있으므로
int row[4] = {-1, 0, 1, 0};
int col[4] = {0, 1, 0, -1};

하지만 바라보고 있는 방향으로 부터 시계 반대방향으로 90도 회전한 곳부터 탐색해야한다

라고하면 북->서->남->동->북 .... 이므로

idx를 1씩 증가시키면 북->동->남->서가 되어버려 틀린다  d = (d+1)%4 사용 불가능 

이런경우에는 turn을 하는 함수를 따로 만들어주면된다 

int turnLeft(int dir) { //지금 바라보고있는 방향이 dir인 경우 이동해야하는 곳(row,col) 의 idx

    //북 -> 서 -> 남 -> 동 ( index -1 )

    if (dir - 1 < 0) return 3;
    return dir - 1;

}

 

 

똑같지만, 조금은 다른 방식

 

    //상하좌우(이동을 위해) 
    int row[4] = {-1, 1, 0, 0};
    int col[4] = {0, 0, -1, 1};
    
    
        //상하좌우 탐색
        for (int i = 0; i < 4; i++) {
            int r = nr + row[i];
            int c = nc + col[i];
        }

 

 

 

728x90