문제링크 : https://programmers.co.kr/learn/courses/30/lessons/49190


아이디어

  • 사방이 막히는 경우
    • 이미 지난 점을 다시 지나올때, 단, 이전에 도착한 방향과 똑같지 않아야함
      • 지난점을 체크하고
      • 지나온 방향도 체크해야함, 이때 역방향도 체크
    • X자를 그리며 화살표가 이동하는 경우
      • 점을 2번 이동하는 걸로 하자
      • 방이 최대 200000
      • 중복체크할때 배열로 하면 너무커짐
      • map으로 중복 체크하자

시간복잡도 계산

  • 배열 크기 전체 순회 : O(N)

자료구조

  • 중복체크 : map<pair<int, int>, bool>
    • 들어가는값 : 각각 y,x축 좌표
    • 최소값 : -2e5
    • 최대값 : 2e5
      • 중복 방향 체크 : map<tuple<int, int, int, int>,bool>
      • int pre : 이전 방향을 확인

코드(C++)

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <vector>
#include <map>
#include <tuple>
 
using namespace std;
 
map<pair<intint>bool> chk;
map<tuple<intintintint>bool> dirchk;
 
int dy[] = {-1,-1,0,1,1,1,0,-1};
int dx[] = {0,1,1,1,0,-1,-1,-1};
 
int solution(vector<int> arrows) {
    int cnt=0;
    
    int y = 0;
    int x = 0;
    chk[make_pair(y,x)] = 1;
    
    
    for(int i=0; i<arrows.size(); i++) {
        int tmp = 2;
        while(tmp--) {
            int ed = arrows[i];
            
            int ny = y + dy[ed];
            int nx = x + dx[ed];
            
            // 도착점이 중복값이면서, 같은 방향이 아닐경우
            if(chk[make_pair(ny,nx)] && dirchk[{ny,nx,y,x}] ==false) {
                cnt++;
            }
            
            chk[{ny, nx}] = 1;
            dirchk[{ny,nx,y,x}] = 1;
            dirchk[{y,x,ny,nx}] = 1;
            
            y = ny;
            x = nx;
        }
        
    }
    return cnt;
}
 
cs

문제유형

  • 시뮬레이션 - 새로생기는 영역 구하기
    • 새로 영역 생기는 경우 : 이미 지나온 간선 && 같은 방향으로 들어오지 않아야함
    • map 사용할경우 노드 너무많아지고, 음수 사용하기 위해 map 사용

+ Recent posts