Published 2022. 2. 17. 15:50

문제 링크

http://icpc.me/2481

 

2481번: 해밍 경로

길이가 같은 두 개의 이진수 코드 w1과 w2가 있다고 하자. 이 두 코드 사이의 해밍 거리(Hamming distance)는 w1과 w2의 각 비트를 왼쪽부터 오른쪽으로 차례대로 비교할 때 서로 다른 값을 가진 비트의

www.acmicpc.net

풀이

해밍 거리가 1인 경우는 비트 하나만 다른 것을 의미하기 때문에 비트가 하나만 다른 것들을 모두 그래프로 만든 후에 bfs를 돌리면 된다.

비트 하나만 바꿀 때는 XOR연산을 하면 된다. 그래프를 만들 때는 N개의 수에 k번 비트 연산을 하고 그 수가 존재하는지 map으로 확인하면 O(NKlogN)에 만들 수 있다.

cf) 입력을 int형으로 받아서 2시간 가까이 뇌절을 했다. 30자리 수니 매우 크다.. 조심하자..

코드

#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
#define sz(x) int((x).size())

const int N = 1e5 + 5;
int arr[N], par[N], n, k; 
map<int, int> bit;
vector<int> v[N];

int main() {
    scanf("%d %d", &n, &k);
    for (int i = 1; i <= n; i++) {
        char inp[33]; scanf("%s", inp);
        int cal = 0, pw = 1;
        for (int i = k - 1; i >= 0; i--) {
            cal += (inp[i] - '0') * pw;
            pw <<= 1;
        }
        bit[cal] = i;
    }

    for (auto [num, idx] : bit) {
		for (int i = 0; i < k; i++) {
			if (bit.count(num ^ (1 << i))) {
                v[idx].push_back(bit[num ^ (1 << i)]);
            }
		}
	}

    queue<int> q;    
    q.push(1);
    par[1] = -1;
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        for (auto nxt : v[cur]) {
            if (par[nxt]) continue;
            q.push(nxt);
            par[nxt] = cur;
        }         
    }

    int m; scanf("%d", &m);
    while (m--) {
        int inp; scanf("%d", &inp);
        if (!par[inp]) {
            printf("-1\n");
            continue;
        }
        vector<int> ans;
        while (inp != -1) {
            ans.push_back(inp);
            inp = par[inp];
        }
        for (int i = sz(ans) - 1; i >= 0; i--) printf("%d ", ans[i]);
        printf("\n");
    }
}

'Algorithm > BOJ' 카테고리의 다른 글

[백준] 1126 같은 탑  (0) 2022.02.26
[백준] 2662 기업투자  (0) 2022.02.23
[백준] 1533 길의 개수  (0) 2022.02.03
[백준] 12850 본대 산책 2  (0) 2022.01.27
[백준] 13977 이항 계수와 쿼리  (0) 2022.01.25
복사했습니다!