D - ビーズ列 / Bead Sequence 解説 by admin
Claude 4.6 Opus (Thinking)Overview
Given a bead sequence of length \(N\) (\(N \leq 25\)), the problem asks to find the minimum number of operations to reach a target state \(T\) from an initial state \(S\), using three types of operations: cyclic left shift, cyclic right shift, and pattern duplication. This can be solved by exploring the state space with BFS (Breadth-First Search).
Analysis
- The bead sequence consists of only two types of characters,
AandB, with a maximum length of 25. Therefore, there are at most \(2^{25} = 33{,}554{,}432\) possible states for the bead sequence. - Since we need to find the “minimum number of operations,” this can be viewed as a shortest path problem on a graph where each state is a vertex and each operation is an edge. Since all edge weights are 1, BFS is optimal.
- The number of transitions from each state is: one for left rotation, one for right rotation, and (the number of proper divisors of \(N\)) for pattern duplication, totaling \(O(\sqrt{N})\), which is small.
- Since \(N \leq 25\), each state can be represented as a bit string (integer). For example, mapping
Ato 0 andBto 1, a string of length \(N\) corresponds to an \(N\)-bit integer.
Algorithm
- Bit representation of states: Convert strings to integers. The first character corresponds to the most significant bit.
- Preprocessing: Enumerate all positive divisors of \(N\) that are less than \(N\).
- BFS: Start BFS from the initial state \(S\), and for each state, try the following transitions:
- Left rotation: Shift the bit string left by 1 bit, placing the overflowed bit at the least significant position.
((u << 1) & mask) | (u >> (N-1)) - Right rotation: Shift the bit string right by 1 bit, placing the overflowed bit at the most significant position.
(u >> 1) | ((u & 1) << (N-1)) - Pattern duplication: For each divisor \(d\), extract the upper \(d\) bits (corresponding to the first \(d\) characters) and create an integer by repeating them \(N/d\) times.
- Left rotation: Shift the bit string left by 1 bit, placing the overflowed bit at the least significant position.
- If the target state \(T\) is reached, output the step count at that point. If BFS completes without reaching it, output
-1.
Concrete example: \(N = 4\), \(S = \) ABAB (= 0101 = 5), \(T = \) AAAA (= 0000 = 0)
- Left rotation: ABAB → BABA
- Pattern duplication (\(d=2\)): ABAB → Repeat first 2 characters AB twice → ABAB (unchanged)
- Pattern duplication (\(d=1\)): ABAB → Repeat first 1 character A four times → AAAA (goal!)
Therefore, it is reachable in 1 operation.
Complexity
- Time complexity: \(O(2^N \cdot d(N))\) (\(d(N)\) is the number of divisors of \(N\). Each state is visited at most once, and \(O(d(N))\) transitions are examined from each state)
- Space complexity: \(O(2^N)\) (visited array and BFS queue)
When \(N = 25\), \(2^{25} \approx 3.4 \times 10^7\), and since each BFS operation consists only of bit operations which are fast, this is well within time limits.
Implementation Notes
By encoding strings as integers, state comparison and storage can be done in \(O(1)\).
Allocating the
visitedarray with size \(2^N\) and using direct access instead of a hash map enables fast processing.For the pattern duplication implementation, use
(u >> (N - d)) & ((1 << d) - 1)to extract the upper \(d\) bits, then concatenate them \(N/d\) times by left-shifting and OR-ing.By managing each BFS level with
sz, the step count is tracked accurately.Source Code
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N;
string S, T;
cin >> N >> S >> T;
auto to_int = [&](const string& s) {
int val = 0;
for (int i = 0; i < N; i++) {
val = (val << 1) | (s[i] == 'B' ? 1 : 0);
}
return val;
};
int src = to_int(S);
int dst = to_int(T);
if (src == dst) { cout << 0; return 0; }
int mask = (1 << N) - 1;
int total = 1 << N;
vector<int> divisors;
for (int d = 1; d < N; d++) {
if (N % d == 0) divisors.push_back(d);
}
vector<bool> visited(total, false);
visited[src] = true;
queue<int> q;
q.push(src);
int steps = 0;
while (!q.empty()) {
steps++;
int sz = q.size();
while (sz--) {
int u = q.front(); q.pop();
auto try_add = [&](int v) -> bool {
if (!visited[v]) {
if (v == dst) return true;
visited[v] = true;
q.push(v);
}
return false;
};
// Left rotate
int left = ((u << 1) & mask) | ((u >> (N-1)) & 1);
if (try_add(left)) { cout << steps; return 0; }
// Right rotate
int right = (u >> 1) | ((u & 1) << (N-1));
if (try_add(right)) { cout << steps; return 0; }
// Pattern duplication
for (int d : divisors) {
int pattern = (u >> (N - d)) & ((1 << d) - 1);
int new_val = 0;
for (int i = 0; i < N / d; i++) {
new_val = (new_val << d) | pattern;
}
if (try_add(new_val)) { cout << steps; return 0; }
}
}
}
cout << -1;
return 0;
}
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: