문제에서 키가 String으로 주어질 경우,

연산이 느리기 때문에 숫자로 변환한다.

 

* 변환 원리

String -> Usigned long long

12자리 까지는 Ull 타입으로 표현이 가능하다

a ~ z 를 1~26 숫자로 나타낸다.

알파벳은 최대 26이므로, 2진법 5자리수로 나타낸다.

예시) 

key : apple

 

a : 1 = 00001 (2)

p : 16 = 10000 (2)

p : 16 = 10000 (2)

l :  12 = 01100 (2)

e : 5 = 00101 (2)

 

=> 00001 10000 10000 01100 00101 (2) 로 나타낼 수 있음.

 

 

이것을 코드로 구현한다면?

typedef unsigned long long ull;

ull stoull(char key[]) {
	ull rtn = 0;
	
	for (int i = 0; key[i]; i++) {
		rtn = (rtn << 5) + key[i] - 'a' + 1;
	}
	
	return rtn;
}

5자리씩 Shift연산 을 하며 계산한다.

 

(key[i] - 'a' + 1) 을 하는 이유는 알파벳 a를 0 이 아닌 1로 표현하기 위함이다

왜냐하면 a를 0으로 표현할 경우

a = 0

aa = 0

둘다 0 으로 같은 값으로 취급될 수 있기 때문이다.


문제보기 >> [BOJ] 17144 : 미세먼지 안녕!



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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
 
//2019-06-20
//BOJ :: 17144 미세먼지안녕!
 
public class Main17144_미세먼지안녕 {
    private static int R, C, T;
    private static int[][] map, nmap;
    static int[] dy = { -1100 };
    static int[] dx = { 00-11 };
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        map = new int[R][C];
        for (int i = 0; i < R; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < C; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        } //// input
 
        for (int t = 0; t < T; t++) {
            spreadDust();
        }
        
        int ans=0;
        for(int i=0;i<R;i++) {
            for(int j=0;j<C;j++) {
                if(map[i][j]>0) {
                    ans+=map[i][j];
                }
            }
        }
        
        System.out.println(ans);
 
    }
 
    public static void spreadDust() {
        ArrayList<pair> airCleanr = new ArrayList<>();
        nmap = new int[R][C];
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                if (map[i][j] > 0) {// 먼지인 경우
                    int cnt = 0;
                    for (int d = 0; d < 4; d++) {
                        int ny = i + dy[d];
                        int nx = j + dx[d];
                        if (ny < 0 || ny > R - 1 || nx < 0 || nx > C - 1 || map[ny][nx] == -1)
                            continue;
 
                        nmap[ny][nx] += map[i][j] / 5;
                        cnt++;
                    }
                    nmap[i][j] += map[i][j] - (map[i][j] / 5* cnt;
                } else if (map[i][j] == -1) {// 공기청정기 위치.
                    nmap[i][j] = -1;
                    airCleanr.add(new pair(i, j));
                }
            }
        }
 
        for (int i = 0; i < R; i++) {
            map[i] = Arrays.copyOf(nmap[i], C);
        }
 
        cleanAir(airCleanr.get(0), airCleanr.get(1));
 
    }
 
    public static void cleanAir(pair up, pair down) {
        // up : 반시계방향
        // down : 시계방향
 
        for (int i = 0; i < C - 1; i++) {
            if (nmap[up.y][i] == -1 || nmap[down.y][i] == -1) {
                map[up.y][i + 1= 0;
                map[down.y][i + 1= 0;
 
            } else {
                map[up.y][i + 1= nmap[up.y][i];
                map[down.y][i + 1= nmap[down.y][i];
            }
 
            map[0][i] = nmap[0][i + 1];
 
            map[R - 1][i] = nmap[R - 1][i + 1];
        }
 
        for (int j = 0; j < R - 1; j++) {
 
            if (j < up.y) {
                map[j + 1][0= nmap[j][0]; // 위로
                map[j][C - 1= nmap[j + 1][C - 1]; // 아래로
 
            } else if (j >= down.y) {
                map[j + 1][C - 1= nmap[j][C - 1]; // 아래
                map[j][0= nmap[j + 1][0]; // 위로
            }
        }
 
        map[up.y][up.x] = -1;
        map[down.y][down.x] = -1;
 
        //System.out.println();
    }
 
    static class pair {
        int y;
        int x;
 
        public pair(int y, int x) {
            this.y = y;
            this.x = x;
        }
 
    }
 
}
 
cs

'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 2146 : 다리 만들기  (1) 2019.06.05
[BOJ] 17281 :: ⚾ 야구  (2) 2019.06.05
[BOJ] 16236 : 아기상어  (0) 2019.06.05
[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09


문제보기 >> [BOJ] 2146 : 다리 만들기


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main_2146_다리만들기 {
    static int N;
    static int[] dy = { -1100 };
    static int[] dx = { 00-11 };
    static int[][] map;
    static int[][] boundary;
    private static boolean[][] visit;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        boundary = new int[N][N];
        visit = new boolean[N][N];
        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        } ////// input
 
        int chk = 1;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (visit[i][j] || map[i][j] == 0)
                    continue;
                bfs(i, j, chk);
                chk++;
            }
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (boundary[i][j] <1)
                    continue;
                int b = bridge(i, j, boundary[i][j]);
                min = min > b? b:min;
            }
        }
 
        System.out.println(min);
    }// end of main
 
    static void bfs(int y, int x, int chk) {
        Queue<pair> que = new LinkedList<>();
        que.add(new pair(y, x));
        visit[y][x] = true;
        boundary[y][x] = -1;
        while (!que.isEmpty()) {
            pair p = que.poll();
            int py = p.y;
            int px = p.x;
 
            for (int i = 0; i < 4; i++) {
                int ny = py + dy[i];
                int nx = px + dx[i];
                if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || visit[ny][nx])
                    continue;
                if (map[ny][nx] == 1) {
                    que.add(new pair(ny, nx));
                    visit[ny][nx] = true;
                    boundary[ny][nx] = -1;
                }
                if (map[ny][nx] == 0) {
                    boundary[py][px] = chk;
                }
            }
        }
    }
 
    static int bridge(int y, int x, int me) {
        int[][] visit2 = new int[N][N];
        Queue<pair> que = new LinkedList<>();
        que.add(new pair(y, x));
        visit2[y][x] = 1;
        int len = 0;
        while (!que.isEmpty()) {
 
            len++;
            int qSize = que.size();
            for (int q = 0; q < qSize; q++) {
                pair p = que.poll();
                int py = p.y;
                int px = p.x;
 
                for (int i = 0; i < 4; i++) {
                    int ny = py + dy[i];
                    int nx = px + dx[i];
                    if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || visit2[ny][nx] != 0 || boundary[ny][nx] == -1 || boundary[ny][nx]==me)
                        continue;
                    if (boundary[ny][nx] != 0 && boundary[ny][nx] != -1 && boundary[ny][nx] != me) {
                        //System.out.println("("+ny+","+nx+")");
                        return len-1;
                    }
 
                    if (boundary[ny][nx] ==0) {
                        que.add(new pair(ny, nx));
                        visit2[ny][nx] = len;
                    }
                }
            }
        }
        return len;
    }
 
    static class pair {
        int y;
        int x;
 
        public pair(int y, int x) {
            super();
            this.y = y;
            this.x = x;
        }
    }
}
 
cs


'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 17144 : 미세먼지 안녕!  (1) 2019.06.20
[BOJ] 17281 :: ⚾ 야구  (2) 2019.06.05
[BOJ] 16236 : 아기상어  (0) 2019.06.05
[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09



문제보기 >> [BOJ] 17281 :: ⚾ 야구


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
//BOJ:: 17281 야구 
public class Main17281_야구 {
    static int N;
    static int[][] rst;
 
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(bf.readLine()); // 이닝
        rst = new int[N][10];
        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(bf.readLine());
            for (int j = 1; j < 10; j++) {
                rst[i][j] = Integer.parseInt(st.nextToken());
            }
        } //////// input
 
        visit = new boolean[10];
        player = new int[10];
        player[4= 1;
        max = -1;
        perm(1);
        System.out.println(max);
    }// end of main
 
    static boolean[] visit;
    static int[] player;
    static int max;
    public static void perm(int len) { // 선수 배치하기
        if (len == 4) { // 4번째 타자는 1번.
            perm(len + 1);
            return;
        }
        if (len == 10) {
            // 선택완료
            int score = playGame();
            max = max<score? score:max;
            return;
        }
 
        for (int i = 2; i < 10; i++) {
            if (visit[i])
                continue;
            player[len] = i;
            visit[i] = true;
            perm(len + 1);
            visit[i] = false;
        }
    }
 
    public static int playGame() {
        int score = 0;
        int out;
        boolean[] roo = new boolean[4];
        int hitter = 1;
        
        for (int inning = 0; inning < N; inning++) {
            out = 0;
            Arrays.fill(roo, false);
            while(true) {
                int now = rst[inning][player[hitter]];
                if(hitter==9) hitter = 1;
                else hitter++;
                if (now == 1) { // 안타
                    if(roo[3]) {
                        score++;
                        roo[3]=false;
                    }
                    for(int r=2;r>=1;r--) {
                        if(roo[r]) {
                            roo[r]=false;
                            roo[r+1]=true;
                        }
                    }
                    roo[1]=true;
                } else if (now == 2) { // 2루타
                    if(roo[3]) {
                        score++;
                        roo[3]=false;
                    }
                    if(roo[2]) {
                        score++;
                        roo[2]=false;
                    }
                    if(roo[1]) {
                        roo[1]=false;
                        roo[3]=true;
                    }
                    roo[2]=true;
 
                } else if (now == 3) { // 3루타
                    for(int r=1;r<=3;r++) {
                        if(roo[r]) {
                            score++;
                            roo[r]=false;
                        }
                    }
                    roo[3= true;
                } else if (now == 4) { // 홈런
                    for(int r=1;r<=3;r++) {
                        if(roo[r]) {
                            score++;
                            roo[r]=false;
                        }
                    }
                    score++//타자도 홈으로.
                } else if (now == 0) { // 아웃
                    out++;
                    if (out == 3) {
                        break;
                    }
                }
            }
        }// end of for
        return score;
    } //end of playGame
}// end of class
 
cs

 

Comment

정말 귀찮은 문제다~

 

순열로 타자를 뽑아준다. 여기서 1번 타자가 4번째 순서는 고정인 것에 주의해야 한다!

타자를 뽑은 후에는 주어진 조건대로 게임을 진행하고, 최대 점수를 갱신한다.

'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 17144 : 미세먼지 안녕!  (1) 2019.06.20
[BOJ] 2146 : 다리 만들기  (1) 2019.06.05
[BOJ] 16236 : 아기상어  (0) 2019.06.05
[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09

 

 

문제보기>> [BOJ] 16236 : 아기상어

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
//2019-06-01
//BOJ 16236 아기상어
 
/*
 * 아기상어의 초기 크기 : 2
 * 자신보다 큰 물고기가 있는 칸은 지날 수 없다. 나머지 칸은 지날 수 있다.
 * 자신의 크기보다 작은 물고기만 먹을 수 있다. 
 * ==> 크기가 같은 물고기는 먹을수는 없지만, 지나갈 수는 있다.
 * 
 * 더 이상 먹을 수 있는 물고기가 공간에 없으면. 엄마 상어에게 도움을 요청한다.
 * 먹을수 있는 물고기가 1마리면 먹으러 간다.
 * 1마리보다 많으면,가장 가까운 물고기를 먹으러 간다 .
 *  지나야하는 칸의 개수의 최솟값.
 *  가까운 물고기가 많으면 : 가장위 -> 가장 왼쪽 
 *  이동과 동시에 물고기를 먹는다. 
 *  물고기를 먹으면, 그 칸은 빈칸이된다.
 *  
 *  자신의 크기와 같은 수의 물고기를 먹으면 크기가 1 증가.
 *  크기가 2인 아기 상어는 물고기를 2마리 먹으면 이됨.
 *  
 */
public class Main_16236_아기상어 {
    static int N, ans;
    static int[][] map;
    static int[] dy = { -1100 };
    static int[] dx = { 00-11 };
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        int sy = -1, sx = -1;
        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                if (map[i][j] == 9) {
                    sy = i;
                    sx = j; // 아기상어 위치 
                }
            }
        } // input
        bfs(sy, sx);
        System.out.println(ans);
    }// end of main
    
    
    public static void bfs(int sy, int sx) {
        int sharksize = 2//초기크기 
        int sharkeat = 0;
        Queue<pair> q = new LinkedList<>();
        ArrayList<pair> fish = new ArrayList<>();
        boolean[][] visit = new boolean[N][N];
        q.add(new pair(sy, sx)); // 아기상어의 초기위치
        visit[sy][sx]=true;
 
        int time = 0;
        while (!q.isEmpty()) {
            
            int qSize = q.size();
            int y=-1, x=-1;
            for (int s = 0; s < qSize; s++) { //1초 단위로 순회 
                
                pair p = q.poll();
                y = p.y;
                x = p.x;
                for (int i = 0; i < 4; i++) {
                    int ny = y + dy[i];
                    int nx = x + dx[i];
 
                    if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || visit[ny][nx] || map[ny][nx]>sharksize)
                        continue;
                    
                    q.add(new pair(ny, nx)); //방문할 수 있는 모든 곳 (빈 곳, 상어 이하 크기의 물고기 )
                    visit[ny][nx] = true;
                    if(map[ny][nx]!=0 && map[ny][nx]<sharksize) { //그 중, 먹을 수 있는 물고기 
                        fish.add(new pair(ny,nx));
                    }
                }
            } // 1초
            time++;
            
            if(fish.size()!=0) { //먹을 물고기가 있다.
                Collections.sort(fish); //조건에 맞는 물고기 찾기. 
                pair meal = fish.get(0);
                fish.clear(); 
                sharkeat++;
                if(sharksize==sharkeat) {
                    sharksize++;
                    sharkeat=0;
                }
                
                map[sy][sx]=0//이전 상어 위치 초기화 
                sy=meal.y;
                sx=meal.x; //상어 위치 변경 
                map[sy][sx] = 9//이동후 상어의 위치 
                
                q.clear(); 
                q.add(meal); //이동 후 상어의 위치부터 다시 bfs 순회. 
                ans+=time; //****** 시간을 더해준다. ******
                time = 0//시간 초기화 
                for(int i=0;i<N;i++) { //visit initialize
                    Arrays.fill(visit[i], false);
                }
                visit[meal.y][meal.x]=true;
            }
            
        } // end of while
    }// end of bfs
 
 
    static class pair implements Comparable<pair> {
        int y;
        int x;
 
        public pair(int y, int x) {
            super();
            this.y = y;
            this.x = x;
        }
 
        @Override
        public int compareTo(pair o) {
            if (this.y == o.y) {
                return this.x - o.x;
            } else {
                return this.y - o.y;
            }
        }
    }
}// end of class
 
cs

 

< Comment >

5번만에 해결한 아기상어..

이 문제에서 주의해야할 부분은 "더 이상 먹을 수 있는 물고기가 공간에 없으면. 엄마 상어에게 도움을 요청한다." 이다.

 

더이상 먹을 수 있는 물고기가 있는지 없는지 어떻게 알 수 있을까?



나는 ans 와 time을 분리함으로서 해결했다.

상어를 직접 이동시켰을 때, 갈 수 있는곳을 모두 순회해보고 그제서야 먹을 수 있는 물고기가 없다는걸 깨닫는다면 답을 얻을 수 없다.

따라서 나는 물고기를 탐색할때 time을 증가시켜주고,

먹을 물고기를 찾아 먹을 때 ans+=time; time=0; 작업을 해줬다 !

'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 2146 : 다리 만들기  (1) 2019.06.05
[BOJ] 17281 :: ⚾ 야구  (2) 2019.06.05
[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09
[BOJ] 1938 통나무 옮기기  (0) 2019.04.05

문제보기 >> [BOJ] 16235 : 나무재테크



Comment

문제 그대로 구현했다.

우선순위큐를 사용할때 팝하는 과정에서 내 의지와 다르게 팝될 수 있으므로 주의 ..**

우선순위큐 사이즈만큼 팝하고, 다시 애드 할때에는 새로운 큐에 담은 후 옮겨줘야한다

 

 

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
 
//BOJ :: 16235 나무재테크
//2019-04-13
 
public class Main16235_나무재테크 {
    private static int[][] A;
    private static int N,K;
    private static PriorityQueue<pair> trees;
    private static int[][] Y;
    private static int[] dy = {-1,-1,-1,0,0,1,1,1};
    private static int[] dx = {-1,0,1,-1,1,-1,0,1};
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        A = new int[N + 1][N + 1];
        Y = new int[N + 1][N + 1];
 
        trees = new PriorityQueue<>();
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 1; j <= N; j++) {
                A[i][j] = Integer.parseInt(st.nextToken());
                Arrays.fill(Y[i], 5); // 양분 초기값
            }
        }
 
        for (int i = 0; i < M; i++) {// 나무정보
            st = new StringTokenizer(br.readLine(), " ");
            int y = Integer.parseInt(st.nextToken());
            int x = Integer.parseInt(st.nextToken());
            int z = Integer.parseInt(st.nextToken()); // 나무 나이
            trees.add(new pair(y, x, z));
        }
        //////// input
 
        treeInvestment();
        
        System.out.println(trees.size());
    }
 
    public static void treeInvestment() {
        ArrayList<pair> die = new ArrayList<>();
        ArrayList<pair> breed = new ArrayList<>();
        for (int year = 0; year < K; year++) {
            // 봄
            int tsize = trees.size();
            PriorityQueue<pair> newpq = new PriorityQueue<>();
            for (int i = 0; i < tsize; i++) {
            
                pair p = trees.poll();
                int py = p.y;
                int px = p.x;
 
                if (Y[py][px] < p.age) {// 양분이 내 나이보다 적으면 죽는다.
                    die.add(new pair(py,px,p.age));
                    continue;
                }
                
                Y[py][px] -= p.age; // 나이만큼 양분 먹기
                newpq.add(new pair(py, px, p.age+1));
                
                if((p.age+1)%5==0) {//나이가 5의 배수면 
                    breed.add(new pair(py,px,p.age+1));
                }
            }
            trees = new PriorityQueue<>(newpq);
 
            // 여름
            for(pair p : die) {
                int py = p.y;
                int px = p.x;
                
                Y[py][px] += p.age/2;
            }
            die.clear();
        
            //가을
            for(pair p : breed) {
                int py = p.y;
                int px=p.x;
                for(int i=0;i<8;i++) {
                    int ny = py+dy[i];
                    int nx = px+dx[i];
                    
                    if(ny<1 || ny>|| nx<1 || nx>N) continue;
                    
                    trees.add(new pair(ny,nx,1));
                }
            }
            breed.clear();
            
            //겨울 
            for(int i=1;i<=N;i++) {
                for(int j=1;j<=N;j++) {
                    Y[i][j] += A[i][j];
                }
            }
        
        }//year term 
    
        return;
 
    }
 
    static class pair implements Comparable<pair> {
        int y;
        int x;
        int age;
        public pair(int y, int x, int age) {
            super();
            this.y = y;
            this.x = x;
            this.age = age;
        }
        @Override
        public int compareTo(pair o) {
            return this.age - o.age;
        }
    }
}
 
cs

'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 17281 :: ⚾ 야구  (2) 2019.06.05
[BOJ] 16236 : 아기상어  (0) 2019.06.05
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09
[BOJ] 1938 통나무 옮기기  (0) 2019.04.05
[SWEA] 2383. 점심식사 시간  (5) 2019.04.04

문제 >> [BOJ] 15685. 드래곤 커브



전형적인 시뮬레이션 문제.


방향의 규칙에 대해서 생각해보며 풀었습니다. 


→  ↑ ← ↓  순서로 드래곤커브가 진행된다는 것을 발견하였고, 순서대로 배열에 넣어 인덱스를 활용해 방향을 전환했습니다.



문제에서 주어진 예시를 보면 ,


시작 방향이 오른쪽 일때,


0세대 

 →  


1세대

 →   ↑ 


2세대

 →   ↑ ← ↑


3세대

 →   ↑ ← ↑ ← ↓ ←  ↑


순서로 진행하고 있고, 이들의 규칙은 다음과 같습니다.


1. 이전 세대의 방향들은 LILF로 팝한다.


2. 방향을 회전해서 진행하여 상단에 push하고 원래의 방향을 하단에 add한다.


예시 )


1세대

 →   ↑ 


nowQ : (상) ↑   → (하) 


LILF로 pop


  ↑   회전 후 ==> ← 


(회전된 방향을 상단에 푸시, 원래방향 하단에 애드)

nextQ : (상)   ←  ↑   (하) 


-----------------------------------


nowQ : (상)  → (하) 


LILF로 pop


   →  회전 후 ==> ↑ 


(회전된 방향을 상단에 푸시, 원래방향 하단에 애드)

nextQ : (상)   ↑  ←  ↑ →  (하) 


-----------------------------------

상단부터 팝하면 2세대가 완성되는 것을 확인할 수 있습니다.


2세대

 →   ↑ ← ↑



설명처럼 상단과 하단 모두에 삽입 하기 위해 덱을 사용해 구현했습니다.




<<java>>

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.StringTokenizer;
 
//BOJ :: 15685 드래곤커브
//2019-04-08
public class Main {
    static int[] dy = { 0-101 };
    static int[] dx = { 10-10 }; // 오 상 왼 하
    private static boolean[][] map;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine()); // 드래곤 커브의 개수
        map = new boolean[103][103];
        StringTokenizer st;
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            int g = Integer.parseInt(st.nextToken());
 
            bfs(x, y, d, g);
        }
 
        
        int ans =0;
        for(int i=0;i<100;i++) {
            for(int j=0;j<100;j++) {
                if(map[i][j]&&map[i+1][j]&&map[i][j+1]&&map[i+1][j+1]) {
                //    System.out.println(i+" "+j);
                    ans++;
                }
            }
        }
        System.out.println(ans);
 
    }
 
    public static void bfs(int x, int y, int d, int generation) {
        Deque<Integer> now = new LinkedList<>();
 
        Deque<Integer> next = new LinkedList<>();
        map[y][x]=true;
        int ny = y+dy[d];
        int nx = x+dx[d];
        if(ny<0 || ny>100 || nx<0 || ny>100return;
        map[ny][nx]=true;
        y=ny;
        x=nx;
        now.add(getNextdir(d));
        if(generation==0return;
        int g = 0;
        while (!now.isEmpty()) {
            g++;
            int size = now.size();
 
                for(int i=0;i<size;i++) {
                    int dir = now.pop();
                    ny = y+dy[dir];
                    nx = x+dx[dir];
                    if(ny<0 || ny>100 || nx<0 || ny>100break;
                    
                    map[ny][nx] = true;
                    
                    int nd = getNextdir(dir);
                    
                    next.push(nd);
                    next.add(dir);
                    y=ny;
                    x=nx;
            }
 
            if(g==generation) return;
            now.clear();
            now = new LinkedList<>(next);
            next.clear();
//            y=ny;
//            x=nx;
        }
 
    }
    public static int getNextdir(int d) {
        if(d==3return 0;
        else return d+1;
    }
 
    static class pair {
        int y;
        int x;
        int dir;
 
        public pair(int y, int x, int dir) {
            super();
            this.y = y;
            this.x = x;
            this.dir = dir;
        }
    }
}
 
cs




<<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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <queue>
#include <deque>
using namespace std;
 
int n,generation;
int dx[] = {0,-1,0,1};
int dy[] = {1,0,-1,0};
bool map[101][101= {false};
deque<int> dq;
 
void dragon_curve(int nx,int ny, int g){
    
    queue<int> q;
    
    if(g == generation) return;
    
    int dq_size = dq.size();
    
    for(int i=0;i<dq_size;i++){
        int a = dq.front();
        dq.pop_front();
        q.push(a);
    }
    
    for(int i=0;i<dq_size;i++){
        int d = q.front();
        q.pop();
        dq.push_back(d);
        
        int nd = (d+1)%4;
        
        nx += dx[nd];
        ny += dy[nd];
        
        if(nx <0 || nx >100 || ny<0 || ny>100continue;
        
        map[nx][ny]= true;
        dq.push_front(nd);
    }
    
    dragon_curve(nx,ny,g+1);
}
 
void count_box(){
    int cnt = 0;
   
    for(int i=0;i<=99;i++){
        for(int j=1;j<=100;j++){
            if(map[i][j] && map[i][j-1&& map[i+1][j] && map[i+1][j-1])
                cnt++;
        }
    }
    printf("%d\n", cnt);
}
 
int main(){
    scanf("%d",&n);
    
    int x,y,d;
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d",&y,&x,&d,&generation);
        while(!dq.empty()) dq.pop_front();
        
        map[x][y] = true;
        x += dx[d];
        y += dy[d];
        map[x][y] = true;
        dq.push_front(d);
        
        dragon_curve(x,y,0);
    }
    
    count_box();
    
    return 0;
}
 
cs


'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 16236 : 아기상어  (0) 2019.06.05
[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 1938 통나무 옮기기  (0) 2019.04.05
[SWEA] 2383. 점심식사 시간  (5) 2019.04.04
[SWEA] 1949. 등산로 조성  (0) 2019.04.01

문제 >> [BOJ] 1938. 통나무 옮기기




저는 기본적으로 통나무의 위치를 가운데 좌표와 모양(세로/가로)의 정보로 파악했습니다.

  1. 출발 통나무와 도착 통나무의 위치를 저장.

  1. bfs로 진행

** 4차원의 visit 배열

  • 통나무 모양에 따라서

  • 5가지 행위에 대해서



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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
 
//BOJ :: 1938 통나무 옮기기     
public class Main1938_통나무옮기기2 {
    private static char[][] map;
    private static boolean[][][][] visit;
    private static int N;
    private static ArrayList<pair> nowLog;
    private static ArrayList<pair> destLog;
    private static log end;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        nowLog = new ArrayList<>();
        destLog = new ArrayList<>();
 
        map = new char[N][N];
        visit = new boolean[5][2][N][N];
 
        for (int i = 0; i < N; i++) {
            String str = br.readLine();
            for (int j = 0; j < N; j++) {
                map[i][j] = str.charAt(j);
                if (map[i][j] == 'B')
                    nowLog.add(new pair(i, j));
                if (map[i][j] == 'E')
                    destLog.add(new pair(i, j));
 
            }
        } //// input
 
        Collections.sort(nowLog);
        Collections.sort(destLog);
        int type;
        if (nowLog.get(0).y == nowLog.get(1).y) type = 2else type = 1;
        log start = new log(nowLog.get(1).y, nowLog.get(1).x, type, 0);
 
        if (destLog.get(0).y == destLog.get(1).y) type = 2else type = 1;
        end = new log(destLog.get(1).y, destLog.get(1).x, type, 0);
        System.out.println(bfs(start));
    } // end of main
 
    static int[] dy = { -1100-1-111 };
    static int[] dx = { 00-11-11-11 }; // 상하좌우//대각선
 
    public static int bfs(log start) {
 
        Queue<log> q = new LinkedList<>();
        q.add(start);
        // visit[][start.type-1][start.y][start.x] = true;
        while (!q.isEmpty()) {
            log now = q.poll();
            int y = now.y;
            int x = now.x; // 통나무의 mid 정보
            int type = now.type;
            int cnt = now.cnt;
            // 종료조건 확인
            if (y == end.y && x == end.x && type == end.type) {
                return cnt;
            }
 
            for (int i = 0; i < 5; i++) {
                if (i == 4) { // 회전
                    boolean isPossible = true;
                    // 회전할 수 있는 범위 확인.
                    for (int chk = 0; chk < 8; chk++) {
                        int ny = y + dy[chk];
                        int nx = x + dx[chk];
                        if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || map[ny][nx] == '1') {
                            isPossible = false;
                            break;
                        }
                    }
                    if (!isPossible) continue;
                    int ntype;
                    if (type == 1) ntype = 2;
                    else ntype = 1;
                    if (!visit[i][type - 1][y][x]) {
                        q.add(new log(y, x, ntype, cnt + 1));
                        visit[i][type - 1][y][x] = true;
                    }
 
                } else if (i < 4) {// 상하좌우 이동
                    int ny = y + dy[i];
                    int nx = x + dx[i];
                    if (ny < 0 || ny > N - 1 || nx < 0 || nx > N - 1 || map[ny][nx] == '1'
                            || visit[i][type - 1][ny][nx])
                        continue;
                    if (type == 1) { // |
                        int topY = ny - 1;
                        int bottomY = ny + 1;
                        if (topY < 0 || bottomY > N - 1 || map[topY][nx] == '1' || map[bottomY][nx] == '1'continue;
                    } else { // -
                        int leftX = nx - 1;
                        int rightX = nx + 1;
                        if (leftX < 0 || rightX > N - 1 || map[ny][leftX] == '1' || map[ny][rightX] == '1'continue;
                    }
                    visit[i][type - 1][ny][nx] = true;
                    q.add(new log(ny, nx, type, cnt + 1));
                }
            }
        }
        return 0;
    }
 
    static class log {
        int y;
        int x;
        int type; // 1 : | // 2: -
        int cnt;
        public log(int y, int x, int type, int cnt) {
            super();
            this.y = y;
            this.x = x;
            this.type = type;
            this.cnt = cnt;
        }
    }
 
    static class pair implements Comparable<pair> {
        int y;
        int x;
        public pair(int y, int x) {
            super();
            this.y = y;
            this.x = x;
        }
        @Override
        public int compareTo(pair o) {
            if (o.x == this.x)
                return o.x - this.x;
            else if (o.y == this.y) {
                return o.y - this.y;
            }
            return -1;
        }
    }
}
cs


'Algorithm Problem Solving' 카테고리의 다른 글

[BOJ] 16235 : 나무재테크  (1) 2019.04.13
[BOJ] 15685. 드래곤 커브  (5) 2019.04.09
[SWEA] 2383. 점심식사 시간  (5) 2019.04.04
[SWEA] 1949. 등산로 조성  (0) 2019.04.01
[BOJ] 1805. 나무자르기  (4) 2019.03.22

+ Recent posts