https://www.acmicpc.net/problem/18112

 

18112번: 이진수 게임

첫 번째 줄에 길이 L의 ‘시작 이진수’가 주어진다. 두 번째 줄에 길이 K의 ‘목표 이진수’가 주어진다. (1 ≤ L, K ≤ 10)

www.acmicpc.net

  1. 맨 앞 숫자를 제외한 한 자리 숫자를 보수로 바꾸기
  2. 현재 수에 1 더하기
  3. 현재 수에 1 빼기 (현재 수가 자연수일 때만 해당)

위 과정을 반복하여 시작 이진수 s가 목표 이진수 e가 되는 최소 동작 횟수를 출력하는 문제로 오랜만에 bfs입니다.

입력은 10자리 이진수로 주어지며, 저는 이 수를 10진수로 변환하여 비트마스킹을 이용하였습니다.

 

이 풀이의 로직은

먼저, 이진수를 10진수로 변환하고, s를 시작으로 bfs 탐색합니다.

 

그 다음은 x가 0인 경우를 제외하고 한 비트씩 변경된 값을 queue에 넣습니다.

이 과정에서 bit가 x / 2보다 커진다면 마지막 비트이므로 break를 걸어줍니다.

 

e가 10자리 이진수이므로 1024보다 작은 수입니다.

따라서 x + 1이 1024보다 작은 경우에만 queue에 넣어주면 됩니다.

 

그리고 e는 음수가 아니므로 x가 자연수일 경우에만 x - 1을 queue에 넣어줍니다.

 

위의 과정을 반복하여 e에 도착하면 t를 리턴하여 출력합니다.

 

 

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
#include <iostream>
#include <queue>
#include <string>
#define MAX 10
using namespace std;
 
string str1, str2;
bool visit[1 << MAX];
int s, e;
 
int bfs() {
    queue<int> q;
    q.push(s);
    visit[s] = 1;
    for (int t = 0!q.empty(); t++) {
        int qsize = q.size();
        while (qsize--) {
            int x = q.front();
            q.pop();
 
            if (x == e) {
                return t;
            }
 
            int bit = 1;
            while (1) {
                if (!x) break;
                if (x & bit) {
                    if (bit > x / 2break;
                }
 
                int next = x ^ bit;
                if (!visit[next]) {
                    q.push(next);
                    visit[next] = true;
                }
                bit <<= 1;
            }
 
            if (x + 1 < 1024 && !visit[x + 1]) {
                q.push(x + 1);
                visit[x + 1= true;
            }
            if (x && !visit[x - 1]) {
                q.push(x - 1);
                visit[x - 1= true;
            }
        }
    }
 
    return 0;
}
 
void func() {
    cout << bfs() << '\n';
}
 
void init() {
    int len1 = str1.size();
    int mul = 1;
    for (int i = len1 - 1; i >= 0; i--) {
        if (str1[i] == '1') s += mul;
        mul <<= 1;
    }
 
    int len2 = str2.size();
    mul = 1;
    for (int i = len2 - 1; i >= 0; i--) {
        if (str2[i] == '1') e += mul;
        mul <<= 1;
    }
}
 
void input() {
    cin >> str1 >> str2;
    init();
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 16985 Maaaaaaaaaze  (0) 2022.12.16
boj 14466 소가 길을 건너간 이유 6  (1) 2022.10.13
boj 16946 벽 부수고 이동하기 4  (0) 2022.05.22
boj 5547 일루미네이션  (0) 2022.05.15
boj 16932 모양 만들기  (0) 2022.05.14

https://www.acmicpc.net/problem/17244

 

17244번: 아맞다우산

경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. "아 맞다 우산!!!" 경재 씨는 매번 외출

www.acmicpc.net

챙겨야 하는 물건은 최대 5개이므로 bfs + 비트마스킹이 가능합니다.

visit[x][y][bit]: 좌표 (x, y)에 도착했을 때 찾은 물건의 비트가 bit인 경우의 방문 처리입니다.

비트를 어떻게 할지 고민하다가 chk배열을 사용하여 해당 좌표에 있는 물건의 비트를 정해주었습니다.

나가는 문에 도착했을 때 모든 물건을 찾았을 때만 t를 출력합니다.

 

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
#include <iostream>
#include <queue>
#define MAX 50
using namespace std;
typedef pair<pair<intint>int> pii;
 
queue<pii> q;
char list[MAX][MAX];
bool visit[MAX][MAX][1 << 5];
int chk[MAX][MAX];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, M, bit;
 
void bfs() {
    for (int t = 1!q.empty(); t++) {
        int qsize = q.size();
        while (qsize--) {
            int x = q.front().first.first;
            int y = q.front().first.second;
            int cnt = q.front().second;
            q.pop();
 
            for (int i = 0; i < 4; i++) {
                int nx = x + direct[i][0];
                int ny = y + direct[i][1];
                int ncnt = cnt;
 
                if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
                if (list[nx][ny] == 'X') {
                    int b = chk[nx][ny];
 
                    ncnt |= b;
                }
                if (list[nx][ny] == '#' || visit[nx][ny][ncnt]) continue;
 
                if (list[nx][ny] == 'E' && ncnt == bit) {
                    cout << t << '\n';
                    return;
                }
 
                q.push({ {nx,ny}, ncnt });
                visit[nx][ny][ncnt] = true;
            }
        }
    }
}
 
void input() {
    int cnt = 0;
    cin >> M >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> list[i][j];
            if (list[i][j] == 'S') {
                q.push({ {i,j},0 });
                visit[i][j][0= true;
            }
            else if (list[i][j] == 'X') {
                chk[i][j] = (1 << cnt);
                cnt++;
            }
        }
    }
 
    bit = (1 << cnt) - 1;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    bfs();
 
    return 0;
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 5547 일루미네이션  (0) 2022.05.15
boj 16932 모양 만들기  (0) 2022.05.14
boj 1194 달이 차오른다, 가자.  (0) 2021.04.21
boj 17471 게리맨더링  (0) 2021.04.16
boj 2573 빙산  (0) 2021.04.05

https://www.acmicpc.net/problem/13701

 

13701번: 중복 제거

문제: N개의 정수 A1, A2, ..., AN 을 읽고, 이들 중에서 반복되는 수를 제외하고 남은 N'개의 수 B1, B2, ..., BN’ 을 입력된 순서대로 출력하시오. 이때, 0 ≤ Ai < 225 = 33554432, i=1,2,…,N. 입력의 개수 N은 1

www.acmicpc.net

이 문제는 메모리 제한이 8MB 이므로 2^25만큼의 배열을 사용하면 메모리 초과가 뜹니다.

따라서 이를 수를 구분할 수 있는 몫과 나머지를 이용한 비트마스킹을 이용합니다.

 

인덱스는 몫이 되겠으며, 비트로 사용할 값은 나머지입니다.

x라는 몫에 y라는 나머지가 있는지 비트 연산자로 확인합니다.

y라는 나머지가 있으면 출력, 없으면 return을 시키면 됩니다.

 

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
#include <iostream>
#define MAX 1 + (1 << 20)
using namespace std;
 
int list[MAX];
 
void func(int N) {
    int x = N >> 5;
    int y = N % 32;
    int z = (1 << y);
 
    if (list[x] & z) return;
    list[x] |= z;
    cout << N << ' ';
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    int N;
    while (cin >> N) {
        func(N);
    }
 
    return 0;
}
cs

 

+ Recent posts