※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 20161번 문제인 왜 동전은 하나씩만 뒤집는 거야이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/20161
주어진 동전의 앞면과 뒷면을 나타내는 0과 1을 이용하면 앞의
같은 구간에 여러 번의 동전뒤집기를 시행할 수도 있음에 유의하자. 예를 들어 5개의 동전이 있고
아래는 제출한 소스코드이다.
#include <iostream>
#include <queue>
#include <cstring>
#include <utility>
using namespace std;
int N, K, KK;
int A[101], B[101];
int bdist[1024], val[1024], tmp[1024];
void solve1() {
for (int i = 0; i < N; i++) {
if (A[i] != B[i]) {
cout << -1;
return;
}
}
cout << 0;
}
queue<int> bque;
void solve2() {
KK = (1 << K);
bque.push(0);
bdist[0] = 1;
while (!bque.empty()) {
int cur = bque.front(); bque.pop();
for (int b = 1; b < KK; b <<= 1) {
int nxt = cur ^ (KK - 1) ^ b;
if (!bdist[nxt]) bdist[nxt] = bdist[cur] + 1, bque.push(nxt);
}
}
memset(val, 0x3f, sizeof(val));
int X = 0;
for (int k = 0; k < K; k++) X = X * 2 + A[k];
val[X] = 0;
int b = (KK >> 1);
for (int L = 0, R = K - 1; R < N; L++, R++) {
memset(tmp, 0x3f, sizeof(tmp));
for (int cur = 0; cur < KK; cur++) {
for (int k = 0; k < KK; k++) {
if (!bdist[k]) continue;
int nxt = cur ^ k;
if ((nxt & b) != (B[L] << (K - 1))) continue;
nxt = ((nxt << 1) + A[R + 1]) & (KK - 1);
tmp[nxt] = min(tmp[nxt], val[cur] + bdist[k] - 1);
}
}
swap(val, tmp);
}
X = 0;
for (int k = 0; k < K; k++) {
X = X * 2 + B[N - K + k + 1];
}
if (val[X] < 0x3f3f3f3f) cout << val[X];
else cout << -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> K;
for (int i = 0; i < N; i++) cin >> A[i];
for (int i = 0; i < N; i++) cin >> B[i];
if (K == 1) solve1();
else solve2();
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 11583 // C++] 인경호의 징검다리 (1) | 2024.11.14 |
---|---|
[BOJ 11579 // C++] 초차원전쟁 이나 (1) | 2024.11.13 |
[BOJ 9910 // C++] Progress (1) | 2024.11.11 |
[BOJ 32609 // C++] Beaking Spackwards (3) | 2024.11.08 |
[BOJ 28090 // C++] 특별한 한붓그리기 (3) | 2024.11.07 |