Problem:
パンケーキ
ビ太郎はパンケーキ店で働いている．
この店で最も人気のあるメニューは
N
枚のパンケーキが積み重なったパンケーキタワーである．店で作られているパンケーキには
3
種類の味があり，それぞれ
A
，
B
，
C
と呼ぶことにする．
ここで，パンケーキの並び方が次の条件を満たすようになっているパンケーキタワーを
良いパンケーキタワー
と呼ぶことにする．
すべての味
A
のパンケーキと味
B
のパンケーキの組において，味
A
のパンケーキが味
B
のパンケーキより上にある．
すべての味
A
のパンケーキと味
C
のパンケーキの組において，味
A
のパンケーキが味
C
のパンケーキより上にある．
すべての味
B
のパンケーキと味
C
のパンケーキの組において，味
B
のパンケーキが味
C
のパンケーキより上にある．
例えば，パンケーキの味がそれぞれ上から順に
AABBBC
，
ACC
，
BBBB
となっているパンケーキタワーはどれも良いパンケーキタワーであるが，
AABABCC
，
CA
となっているパンケーキタワーはどれも良いパンケーキタワーではない．
盛り付け担当のビ太郎はパンケーキタワーに対して次の操作を行うことができる．
操作
k
(
2 ≦ k ≦ N
)：上から
k
枚目のパンケーキの下側にフライ返しを差し込み，そこから上のパンケーキをひっくり返す．すなわち，上から
k
枚のパンケーキの並び方を反転させる．
例えば，パンケーキの味が上から順に
ABCB
となっているパンケーキタワーに操作
2
，操作
3
，操作
4
をそれぞれ行った場合，パンケーキの並び方は
BACB
，
CBAB
，
BCBA
となる．
今，
Q
皿のパンケーキタワーがあり，
i
皿目 (
1 ≦ i ≦ Q
) のパンケーキタワーはパンケーキの味が上から順に
S
i,1
S
i,2
… S
i,N
となっている．ビ太郎はそれぞれのパンケーキタワーについて，できる限り少ない回数の操作で良いパンケーキタワーにしたい．
Q
皿のパンケーキタワーの並び方の情報が与えられるので，それぞれのパンケーキタワーについて，良いパンケーキタワーにするのに必要な操作の回数の最小値を求めるプログラムを作成せよ．
制約
2 ≦ N ≦ 13
．
1 ≦ Q ≦ 100000
．
S
i,j
は
A
，
B
，
C
のいずれかである (
1 ≦ i ≦ Q
，
1 ≦ j ≦ N
)．
入力
入力は以下の形式で標準入力から与えられる．
N
Q
S
1
S
2
:
S
Q
ただし，
S
i
(
1 ≦ i ≦ Q
) は長さ
N
の文字列で，その
j
文字目 (
1 ≦ j ≦ N
) は
S
i,j
である．
出力
標準出力に
Q
行出力せよ．
i
行目 (
1 ≦ i ≦ Q
) には，
i
皿目のパンケーキタワーについて，良いパンケーキタワーにするのに必要な操作の回数の最小値を出力せよ．
入出力例
入力例 1
5 3
ABCBA
CCBAB
AAAAA
出力例 1
3
2
0
1
皿目のパンケーキタワーの場合，以下の
3
回の操作を行うことによって良いパンケーキタワーにすることが可能である．
操作
4
を行う．パンケーキの味は上から順に
BCBAA
となる．
操作
2
を行う．パンケーキの味は上から順に
CBBAA
となる．
操作
5
を行う．パンケーキの味は上から順に
AABBC
となる．
2
回以下の操作によって良いパンケーキタワーにすることは不可能であるので，
1
行目に
3
を出力する．
2
皿目のパンケーキタワーの場合，以下の
2
回の操作を行うことによって良いパンケーキタワーにすることが可能である．
操作
5
を行う．パンケーキの味は上から順に
BABCC
となる．
操作
2
を行う．パンケーキの味は上から順に
ABBCC
となる．
1
回以下の操作によって良いパンケーキタワーにすることは不可能であるので，
2
行目に
2
を出力する．
3
皿目のパンケーキタワーの場合，既に良いパンケーキタワーになっているので操作を行う必要がない．したがって，
3
行目に
0
を出力する．
入力例 2
2 5
AC
AC
AC
AC
AC
出力例 2
0
0
0
0
0
パンケーキの並び方が同じであるようなパンケーキタワーが複数個存在する場合もあることに注意せよ．
入力例 3
13 1
ABCCABCBACBAA
出力例 3
9
入力例 4
13 4
CCAAACBAAAABB
BBBCCBCCCBCBC
CCCAAAABBBBBB
AABCBCACBACBA
出力例 4
4
6
2
10
情報オリンピック日本委員会
作 『第 20 回日本情報オリンピック JOI 2020/2021 二次予選競技課題』

Submitted solutions:

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 2 "/home/kuhaku/home/github/algo/lib/string/converter.hpp"

struct string_converter {
    char type(const char &c) const {
        return (std::islower(c) ? 'a' : std::isupper(c) ? 'A' : std::isdigit(c) ? '0' : 0);
    }
    int convert(const char &c) {
        if (!start) start = type(c);
        return c - start;
    }
    int convert(const char &c, const std::string &chars) { return chars.find(c); }
    template <typename T>
    auto convert(const T &v) {
        std::vector<decltype(convert(v[0]))> res;
        res.reserve(v.size());
        for (auto &&e : v) res.emplace_back(convert(e));
        return res;
    }
    template <typename T>
    auto convert(const T &v, const std::string &chars) {
        std::vector<decltype(convert(v[0], chars))> res;
        res.reserve(v.size());
        for (auto &&e : v) res.emplace_back(convert(e, chars));
        return res;
    }
    int operator()(const char &v, char s = 0) {
        start = s;
        return convert(v);
    }
    int operator()(const char &v, const std::string &chars) { return convert(v, chars); }
    template <typename T>
    auto operator()(const T &v, char s = 0) {
        start = s;
        return convert(v);
    }
    template <typename T>
    auto operator()(const T &v, const std::string &chars) {
        return convert(v, chars);
    }

  private:
    char start = 0;
} to_int;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 4 "a.cpp"

int to_hash(const vector<int> &v) {
    int res = 0;
    for (int x : v) res = res * 3 + x;
    return res;
}

vector<int> to_vector(int x, int n) {
    vector<int> res;
    rep (i, n) {
        res.emplace_back(x % 3);
        x /= 3;
    }
    reverse(all(res));
    return res;
}

int main(void) {
    int n, q;
    cin >> n >> q;

    int sz = 1;
    rep (i, n) sz *= 3;
    vector<int> dp(sz, Inf);
    vector<int> v(n, 2);
    rep (i, n + 1) {
        FOR (j, i, n + 1) {
            dp[to_hash(v)] = 0;
            if (j < n)
                v[j] = 1;
        }
        FOR (j, i + 1, n) v[j] = 2;
        if (i < n)
            v[i] = 0;
    }

    queue<int> que;
    rep (i, sz) {
        if (dp[i] == 0)
            que.emplace(i);
    }

    while (!que.empty()) {
        int x = que.front();
        que.pop();
        auto v = to_vector(x, n);
        repn (i, n) {
            reverse(v.begin(), v.begin() + i);
            int h = to_hash(v);
            if (chmin(dp[h], dp[x] + 1)) {
                que.emplace(h);
            }
            reverse(v.begin(), v.begin() + i);
        }
    }

    while (q--) {
        string s;
        cin >> s;
        auto v = to_int(s);
        co(dp[to_hash(v)]);
    }

    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 11140
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 文字列から整数値へ
int encode(const string &S) {
    int res = 0;
    for (auto c: S) res = res * 3 + (c - 'A');
    return res;
}

// 整数値から文字列へ
string decode(int N, int val) {
    string res = "";
    while (val) {
        res += (char)('A' + (val%3));
        val /= 3;
    }
    while (res.size() < N) res += 'A';
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int N, Q;
    cin >> N >> Q;

    // すべての文字列について求めておく
    int MAX = 1;
    for (int i = 0; i < N; ++i) MAX *= 3;
    vector<int> dp(MAX+1, -1);
    queue<int> que;

    // 揃った文字列を始点にする
    for (int a = 0; a <= N; ++a) {
        for (int b = 0; a+b <= N; ++b) {
            string str = string(a, 'A') + string(b, 'B') + string(N-a-b, 'C');
            int val = encode(str);
            dp[val] = 0;
            que.push(val);
        }
    }

    // BFS
    while (!que.empty()) {
        long long val = que.front();
        que.pop();
        auto str = decode(N, val);
        for (int i = 1; i <= N; ++i) {
            string nstr = str;
            reverse(nstr.begin(), nstr.begin() + i);
            int nval = encode(nstr);
            if (dp[nval] == -1) {
                dp[nval] = dp[val] + 1;
                que.push(nval);
            }
        }
    }

    // それぞれの文字列について答える
    for (int q = 0; q < Q; ++q) {
        string S;
        cin >> S;
        cout << dp[encode(S)] << endl;
    }
}
accuracy: 1
time_ms: 410
memory_kb: 11116
final_rank: 6

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
using namespace std;


int encode(const string s) {
	int result = 0;

	for (char c : s) {
		result = result * 3 + c - 'A';
	}
	return result;
}

string decode(int n, int v) {
	string result = "";

	while (v > 0) {
		result += char('A' + v % 3);
		v /= 3;
	}

	while (result.size() < n) {
		result += 'A';
	}
	reverse(result.begin(), result.end());
	return result;
}


int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int n = 0;
	int q = 0;

	cin >> n >> q;

	int max_num_vertexes = 1;
	for (int i = 0; i < n; i++) {
		max_num_vertexes *= 3;
	}

	vector<int> costs(max_num_vertexes, -1);
	deque<int> que;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; i + j <= n; j++) {
			string s = string(i, 'A') + string(j, 'B') + string(n - i - j, 'C');
			int v = encode(s);
			
			costs[v] = 0;
			que.push_back(v);
		}
	}

	while (!que.empty()) {
		int v = que.front(); que.pop_front();
		string s = decode(n, v);
		int n_cost = costs[v] + 1;

		for (int i = 1; i <= n; i++) {
			string ns = s;

			reverse(ns.begin(), ns.begin() + i);
			int u = encode(ns);
			if (costs[u] < 0) {
				costs[u] = n_cost;
				que.push_back(u);
			}
		}
	}

	for (int i = 0; i < q; i++) {
		string s;

		cin >> s;
		cout << costs[encode(s)] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 11076
final_rank: 10

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
using namespace std;

int encode(const string s) {
	int result = 0;

	for (char c : s) {
		result = result * 3 + c - 'A';
	}
	return result;
}

string decode(int n, int v) {
	string result = "";

	while (v > 0) {
		result += char('A' + v % 3);
		v /= 3;
	}

	while (result.size() < n) {
		result += 'A';
	}
	reverse(result.begin(), result.end());
	return result;
}


int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int n = 0;
	int q = 0;

	cin >> n >> q;

	int max_num_vertexes = 1;
	for (int i = 0; i < n; i++) {
		max_num_vertexes *= 3;
	}

	vector<int> cost_list(max_num_vertexes + 1, -1);
	deque<int> que;

	for (int i = 0; i <= n; i++) {
		for (int j = 0; i + j <= n; j++) {
			string s = string(i, 'A') + string(j, 'B') + string(n - i - j, 'C');
			int v = encode(s);
			
			cost_list[v] = 0;
			que.push_back(v);
		}
	}

	while (!que.empty()) {
		int v = que.front(); que.pop_front();
		string s = decode(n, v);
		int n_cost = cost_list[v] + 1;

		for (int i = 1; i <= n; i++) {
			string ns = s;

			reverse(ns.begin(), ns.begin() + i);
			int u = encode(ns);
			if (cost_list[u] < 0) {
				cost_list[u] = n_cost;
				que.push_back(u);
			}
		}
	}

	for (int i = 0; i < q; i++) {
		string s;

		cin >> s;

		cout << cost_list[encode(s)] << endl;
	}

	
	return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 11124
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#include <random>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vvvvll = vector<vvvll>;
using vvvvvll = vector<vvvvll>;
using vvvvvvll = vector<vvvvvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vvvvb = vector<vvvb>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
using vvvvd = vector<vvvd>;
using vvvvvd = vector<vvvvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
using pqr = priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>;

template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

ll gcd(ll(a), ll(b)) {
    if (b == 0)return a;
    ll c = a;
    while (a % b != 0) {
        c = a % b;
        a = b;
        b = c;
    }
    return b;
}


vector<ll> fact, factinv, inv;
ll mod = 1e9;
void prenCkModp(ll n) {
    fact.resize(n + 5);
    factinv.resize(n + 5);
    inv.resize(n + 5);
    fact.at(0) = fact.at(1) = 1;
    factinv.at(0) = factinv.at(1) = 1;
    inv.at(1) = 1;
    for (ll i = 2; i < n + 5; i++) {
        fact.at(i) = (fact.at(i - 1) * i) % mod;
        inv.at(i) = mod - (inv.at(mod % i) * (mod / i)) % mod;
        factinv.at(i) = (factinv.at(i - 1) * inv.at(i)) % mod;
    }

}
ll nCk(ll n, ll k) {
    if (n < k) return 0;
    return fact.at(n) * (factinv.at(k) * factinv.at(n - k) % mod) % mod;
}


int si(string S) {
    int res = 0;
    for (ll i = S.size() - 1; i >= 0; i--) {
        res = res * 3 + (S[i] - 'A');
    }
    return res;
}

int main() {

    ll N, Q;
    cin >> N >> Q;
    ll MA = 4782970;
    vll M(MA, 1e18);
    vll SS(Q);
    queue<int> que;
    vb seen(MA, false);
    rep(q, Q) {
        string S;
        cin >> S;
        SS[q] = si(S);
        sort(all(S));
        que.push(si(S));
        M[si(S)] = 0;
    }

    while (!que.empty()) {
        int t = que.front();
        que.pop();
        if (seen[t])continue;
        seen[t] = 1;
        ll x = 0, y = 1;
        rep(ii, N) {
            x = x * 3 + t / y % 3;
            y *= 3;
            ll r = t / y * y + x;
            if (M[r] <= M[t] + 1)continue;
            if (seen[r])continue;
            M[r] = M[t] + 1;
            que.push(r);
        }

    }


    rep(q, Q) {
        cout << M[SS[q]] << endl;
    }

}
accuracy: 1
time_ms: 410
memory_kb: 43612
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using P = pair<ll, ll>;
using P3 = pair<ll, P>;
using PP = pair<P, P>;
constexpr int INF32 = 1 << 30;
constexpr ll INF64 = 1LL << 61;
// constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int di[] = {0, 1, 0, -1};
constexpr int dj[] = {1, 0, -1, 0};
// constexpr int di8[] = {0, 1, 1, 1, 0, -1, -1, -1};
// constexpr int dj8[] = {1, 1, 0, -1, -1, -1, 0, 1};
constexpr double EPS = 1e-10;
const double PI = acos(-1);

#define ALL(v) (v).begin(),(v).end()
#define REP(i,n) for(int i=0,i_len=n; i<i_len; ++i)

template<typename T1,typename T2> bool chmax(T1 &a, T2 b) { if (a<b) { a=b; return 1; } return 0; }
template<typename T1,typename T2> bool chmin(T1 &a, T2 b) { if (b<a) { a=b; return 1; } return 0; }

int rev(int x, int n){
    int res = 0;
    REP(i,n){
        res = res*3 + x%3;
        x /= 3;
    }
    return res;
}

int solve(){
    int n, q;
    cin >> n >> q;
    int m = 1;
    REP(i,n) m *= 3;
    vector<int> dist(m, INF32);
    queue<int> que;
    for(int i=0;i<=n;i++){
        for(int j=i;j<=n;j++){
            int s = 0;
            for(int k=0,b=1;k<n;k++,b*=3){
                if(k>=i && k<j) s += b;
                if(k>=j) s += b*2;
            }
            dist[s] = 0;
            que.push(s);
        }
    }
    while(!que.empty()){
        int now = que.front();
        que.pop();
        for(int i=2,b=9;i<=n;i++,b*=3){
            int nxt = (now/b)*b + rev(now%b,i);  // 下位i桁をreverse
            if(chmin(dist[nxt], dist[now]+1)){
                que.push(nxt);
            }
        }
    }
    REP(_,q){
        string s;
        cin >> s;
        int x = 0;
        for(int i=0,b=1;i<n;i++,b*=3){
            x += int(s[i]-'A')*b;
        }
        int ans = dist[x];
        if(ans < INF32) cout << ans << endl;
        else cout << -1 << endl;
    }
    return 0;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    solve();
    // int T; cin >> T; REP(t,T) solve();
    // while(!solve());
    return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 11132
final_rank: 4

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0692.cc: パンケーキ
 */

#include<cstdio>
#include<queue>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 13;
const int NTITS = 1594323; // = 3^13

/* typedef */

typedef queue<int> qi;

/* global variables */

char s[MAX_N + 4];
int dp[NTITS], ds[MAX_N];

/* subroutines */

/* main */

int main() {
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);

  int n, qn;
  scanf("%d%d", &n, &qn);

  int ntits = 1;
  for (int i = 0; i < n; i++) ntits *= 3;

  fill(dp, dp + ntits, -1);
  qi q;
  
  for (int a = 0; a <= n; a++)
    for (int b = 0; a + b <= n; b++) {
      int c = n - (a + b);
      int v = 0;
      for (int i = 0; i < b; i++) v = v * 3 + 1;
      for (int i = 0; i < c; i++) v = v * 3 + 2;
      dp[v] = 0;
      q.push(v);
    }

  while (! q.empty()) {
    int u = q.front(); q.pop();

    for (int i = n - 1, w = u; i >= 0; i--, w /= 3) ds[i] = w % 3;

    for (int l = 1; l <= n; l++) {
      reverse(ds, ds + l);

      int v = 0;
      for (int i = 0; i < n; i++) v = v * 3 + ds[i];
      if (dp[v] < 0) {
	dp[v] = dp[u] + 1;
	q.push(v);
      }
      
      reverse(ds, ds + l);
    }
  }

  while (qn--) {
    scanf("%s", s);

    int v = 0;
    for (int i = 0; i < n; i++) v = v * 3 + (s[i] - 'A');

    printf("%d\n", dp[v]);
  }
  return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 10888
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

int encode(const string& S)
{
	int r = 0;
	for (int i = (int) S.size(); --i >= 0;) r = r * 3 + S[i] - 'A';
	return r;
}

int main()
{
	int N, Q, K = 1; cin >> N >> Q;
	for (int n = 0; n <= N; ++n) K *= 3;
	vector<int> D(K, K), E(K, K);
	queue<pair<int, int>> q;
	for (string A; (int) A.size() <= N; A += 'A') for (string B(A); (int) B.size() <= N; B += 'B') {
		q.push({encode(B + string(N - (int) B.size(), 'C')), 0});
	}
	for (; !q.empty(); q.pop()) {
		auto [s, d] = q.front();
		if (D[s] <= d) continue;
		D[s] = E[s] = d++;
		for (int t = s % 3, u = s / 3, k = 9; k < K; k *= 3) {
			int c = u % 3;
			t = t * 3 + c;
			u /= 3;
			int v = u * k + t;
			if (E[v] <= d) continue;
			E[v] = d;
			q.push({v, d});
		}
	}
	while (--Q >= 0) {
		string S; cin >> S;
		cout << D[encode(S)] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 43968
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

string s,t;

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int n,q; cin >> n >> q;
	queue<pair<int,string>> pq;
	auto tran=[](string s)->int{
		int res=0;
		for(char c:s){
			res=res*3+(c-'A');
		}
		return res;
	};
	vector<int> mp(1594324,-1);
	while(q--){
		string S; cin >> S;
		int Num=tran(S);
		if(mp[Num]>=0){
			cout << mp[Num] << "\n";
		}
		else{
			string T=S; sort(T.begin(), T.end());
			pq.push(make_pair(0,T));
			mp[tran(T)]=0;
			while(pq.size()){
				auto p=pq.front(); pq.pop();
				for(int i=2;i<=n;i++){
					s=p.second.substr(0,i);
					t=(i!=n?p.second.substr(i):"");
					reverse(s.begin(), s.end());
					s+=t;
					int num=tran(s);
					if(mp[num]>=0){
						continue;
					}
					else{
						mp[num]=p.first+1;
						pq.push(make_pair(p.first+1,s));
					}
				}
			}
			cout << mp[Num] << "\n";
		}
	}
}
accuracy: 1
time_ms: 720
memory_kb: 10564
final_rank: 11

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>


int pow(int base, int exp) {
	int result{ 1 };
	for (auto i = 0; i < exp; ++i) {
		result *= base;
	}
	return result;
}
int main() {
	int n, q; std::cin >> n >> q;
	std::vector<std::string> dish(q);
	for (auto& s : dish) {
		std::cin >> s;
	}
	std::vector<int> min_step(pow(3, n), INT_MAX);
	std::queue<int> queue;
	for (auto a = 0; a <= n; ++a) {
		int pattern{ 0 };
		for (auto b = 0; a + b <= n; ++b) {
			int p = pattern;
			for (auto c = 0; a + b + c <= n; ++c) {
				min_step[p] = 0;
				queue.push(p);
				p = p * 3 + 2;
			}
			pattern = pattern * 3 + 1;
		}
	}
	std::vector<int> vec(n);
	while (!queue.empty()) {
		const auto top = queue.front(); queue.pop();
		int r = top;
		for (auto i = 1; i <= n; ++i) {
			vec[n - i] = r % 3;
			r /= 3;
		}
		for (auto i = 2; i <= n; ++i) {
			std::reverse(vec.begin(), std::next(vec.begin(), i));
			int pattern{ 0 };
			for (const auto v : vec) {
				pattern *= 3;
				pattern += v;
			}
			if (min_step[pattern] == INT_MAX) {
				min_step[pattern] = min_step[top] + 1;
				queue.push(pattern);
			}
			std::reverse(vec.begin(), std::next(vec.begin(), i));
		}
	}
	for (const auto& s : dish) {
		int pattern{ 0 };
		for (const auto c : s) {
			pattern *= 3;
			if (c == 'B') pattern += 1;
			else if (c == 'C') pattern += 2;
		}
		std::cout << min_step[pattern] << '\n';
	}
}
accuracy: 1
time_ms: 240
memory_kb: 14112
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcountll(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=1LL<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i);}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
ll updivide(ll a,ll b){return (a+b-1)/b;}
int msb(ll v){return 63-__builtin_clzll(v);}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    INT(n);
    vector<int> dist(intpow(3,n),INF);
    vector<int> d={1};
    rep(i,12)d.push_back(d.back()*3);
    auto hash=[&](vector<int> &vec){
        int res=0;
        rep(i,n)res+=vec[i]*d[i];
        return res;
    };
    auto encode=[&](int v){
        vector<int> res(n);
        rep(i,n)res[i]=(v/d[i])%3;
        return res;
    };
    auto BFS=[&](int a,int b,int c){
        vector<int> s;
        rep(i,a)s.push_back(0);
        rep(i,b)s.push_back(1);
        rep(i,c)s.push_back(2);
        int v=hash(s),u;
        queue<int> next;
        next.push(v);
        dist[v]=0;
        while(!next.empty()){
            v=next.front();
            next.pop();
            s=encode(v);
            for(int i=2;i<=n;i++){
                reverse(s.begin(),s.begin()+i);
                u=hash(s);
                if(dist[v]+1<dist[u]){
                    dist[u]=dist[v]+1;
                    next.push(u);
                }
                reverse(s.begin(),s.begin()+i);
            }
        }
    };
    for(int a=0;a<=n;a++){
        for(int b=0;a+b<=n;b++){
            int c=n-(a+b);
            BFS(a,b,c);
        }
    }
    codefor{
        string s;
        cin>>s;
        int v=0;
        rep(i,n){
            if(s[i]=='B')v+=d[i];
            if(s[i]=='C')v+=2*d[i];
        }
        out(dist[v]);
    }
}
accuracy: 1
time_ms: 370
memory_kb: 9564
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define SIZE 81*81*81*3

struct State{
	State(string arg_str,int arg_sum_dist){
		str = arg_str;
		sum_dist = arg_sum_dist;
	}
	State(){

		str = "";
		sum_dist = 0;
	}
	bool operator<(const struct State& arg) const{

		return sum_dist > arg.sum_dist;
	}

	string str;
	int sum_dist;
};

int N;
int POW[14];
int dp[SIZE];

int makeCode(string str){

	int ret = 0;
	for(int i = 0; i < N; i++){

		ret += POW[i]*(str[i]-'A');
	}

	return ret;
}


void calc_dist(int a,int b,int c){

	string base = "";
	for(int i = 0; i < a; i++){

		base += 'A';
	}
	for(int i = 0; i < b; i++){

		base += 'B';
	}
	for(int i = 0; i < c; i++){

		base += 'C';
	}

	dp[makeCode(base)] = 0;

	queue<State> Q;
	Q.push(State(base,0));

	while(!Q.empty()){

		State state = Q.front();
		Q.pop();

		if(state.sum_dist > dp[makeCode(state.str)])continue;

		for(int k = 2; k <= N; k++){

			string L = state.str.substr(0,k);
			string R = state.str.substr(k);

			reverse(L.begin(),L.end());

			string tmp = L+R;

			int next_dist = state.sum_dist+1;
			int code = makeCode(tmp);

			if(dp[code] > next_dist){
				dp[code] = next_dist;
				Q.push(State(tmp,next_dist));
			}
		}
	}
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= 13; i++){

		POW[i] = POW[i-1]*3;
	}

	int num_Q;
	scanf("%d %d",&N,&num_Q);

	for(int i = 0; i < SIZE; i++){

		dp[i] = BIG_NUM;
	}

	for(int a = 0; a <= N; a++){
		for(int b = 0; a+b <= N; b++){
			int c = N-(a+b);

			calc_dist(a,b,c);
		}
	}

	for(int i = 0; i < num_Q; i++){

		string str;
		cin >> str;

		int a = 0,b = 0,c = 0;
		for(int k = 0; k < N; k++){
			if(str[k] == 'A'){

				a++;
			}else if(str[k] == 'B'){

				b++;
			}else{

				c++;
			}
		}

		printf("%d\n",dp[makeCode(str)]);
	}

	return 0;
}
accuracy: 1
time_ms: 740
memory_kb: 10612
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



struct State{
	State(string arg_str,int arg_sum_dist){
		str = arg_str;
		sum_dist = arg_sum_dist;
	}
	State(){

		str = "";
		sum_dist = 0;
	}
	bool operator<(const struct State& arg) const{

		return sum_dist > arg.sum_dist;
	}

	string str;
	int sum_dist;
};

int N;
map<string,int> min_dist;


bool isOK(string str){

	for(int i = 0; i < N-1; i++){
		for(int k = i+1; k < N; k++){
			if((str[i] == 'B'||str[i] == 'C') && str[k] == 'A'){

				return false;
			}
			if(str[i] == 'C' && str[k] == 'B'){

				return false;
			}
		}
	}

	return true;
}

int bfs(string str){

	auto at = min_dist.find(str);
	if(at != min_dist.end()){

		return min_dist[str];
	}

	if(isOK(str)){

		return min_dist[str] = 0;
	}

	priority_queue<State> Q;
	min_dist[str] = 0;
	Q.push(State(str,0));

	while(!Q.empty()){

		State state = Q.top();
		Q.pop();

		if(isOK(state.str)){

			return state.sum_dist;
		}

		for(int k = 2; k <= N; k++){

			string L = state.str.substr(0,k);
			string R = state.str.substr(k);

			reverse(L.begin(),L.end());

			string tmp = L+R;

			int next_dist = state.sum_dist+1;

			auto at = min_dist.find(tmp);
			if(at == min_dist.end()){

				min_dist[tmp] = next_dist;
				Q.push(State(tmp,next_dist));
			}else{

				if(min_dist[tmp] > next_dist){

					min_dist[tmp] = next_dist;
					Q.push(State(tmp,next_dist));
				}
			}
		}
	}

	return -1;
}

int main(){

	int num_Q;
	scanf("%d %d",&N,&num_Q);

	for(int i = 0; i < num_Q; i++){

		string str;
		cin >> str;

		printf("%d\n",bfs(str));
	}

	return 0;
}
accuracy: 0.3508771929824561
time_ms: 70
memory_kb: 3576
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

// template {{{
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;

#define  range(i, l, r) for (i64 i = (i64)(l); i < (i64)(r); (i) += 1)
#define rrange(i, l, r) for (i64 i = (i64)(r) - 1; i >= (i64)(l); (i) -= 1)

#define  whole(f, x, ...) ([&](decltype((x)) container) { return (f)(  begin(container),  end(container), ## __VA_ARGS__); })(x)
#define rwhole(f, x, ...) ([&](decltype((x)) container) { return (f)( rbegin(container), rend(container), ## __VA_ARGS__); })(x)

#define debug(x) cerr << "(" << __LINE__ << ")" << #x << ": " << (x) << endl

constexpr i32 inf   = 1001001001;
constexpr i64 infll = 1001001001001001001ll;

constexpr i32 dx[] = {0, -1, 1, 0, -1, 1, -1, 1}; 
constexpr i32 dy[] = {-1, 0, 0, 1, -1, -1, 1, 1};

struct IoSetup { IoSetup(i32 x = 15){ cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(x); cerr << fixed << setprecision(x); } } iosetup;

template <typename T = i64> T input() { T x; cin >> x; return x; }

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) { range(i, 0, v.size()) { os << v[i] << (i + 1 != (int)v.size() ? " " : ""); } return os; } 
template <typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &in : v) is >> in; return is; }

template <typename T1, typename T2> ostream &operator<<(ostream &os, pair<T1, T2> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { is >> p.first >> p.second; return is; }

template <typename T> vector<T> make_vector(size_t a, T b) { return vector<T>(a, b); }
template <typename... Ts> auto make_vector(size_t a, Ts... ts) { return vector<decltype(make_vector(ts...))>(a, make_vector(ts...)); }

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
// }}}

template< typename T = int >
struct Edge {
  int from, to;
  T cost;
  int idx;

  Edge() = default;

  Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

  operator int() const { return to; }
};

template< typename T = int >
struct Graph {
  vector< vector< Edge< T > > > g;
  int es;

  Graph() = default;

  explicit Graph(int n) : g(n), es(0) {}

  size_t size() const {
    return g.size();
  }

  void add_directed_edge(int from, int to, T cost = 1) {
    g[from].emplace_back(from, to, cost, es++);
  }

  void add_edge(int from, int to, T cost = 1) {
    g[from].emplace_back(from, to, cost, es);
    g[to].emplace_back(to, from, cost, es++);
  }

  void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
    for(int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      a += padding;
      b += padding;
      T c = T(1);
      if(weighted) cin >> c;
      if(directed) add_directed_edge(a, b, c);
      else add_edge(a, b, c);
    }
  }
};

template< typename T = int >
using Edges = vector< Edge< T > >;

template< typename T >
vector< T > bfs(const Graph< T > &g, int s) {
  T max_cost = 0, beet = 0;
  for(auto &es : g.g) {
    for(auto &e : es) max_cost = max(max_cost, e.cost);
  }
  ++max_cost;
  const auto INF = numeric_limits< T >::max();
  vector< T > dist(g.size(), INF);
  vector< queue< int > > ques(max_cost + 1);
  dist[s] = 0;
  ques[0].emplace(s);
  for(T cost = 0; cost <= beet; cost++) {
    auto &que = ques[cost % max_cost];
    while(!que.empty()) {
      int idx = que.front();
      que.pop();
      if(dist[idx] < cost) continue;
      for(auto &e : g.g[idx]) {
        auto next_cost = cost + e.cost;
        if(dist[e.to] <= next_cost) continue;;
        dist[e.to] = next_cost;
        beet = max(beet, dist[e.to]);
        ques[dist[e.to] % max_cost].emplace(e.to);
      }
    }
  }
  return dist;
}

int to_v(const string &s) {
  int res = 0, k = 1;
  for (auto &c : s) {
    res += k * (c - 'A');
    k *= 3;
  }
  return res;
};

void make_G(int i, string &s, int n, Graph<int> &G) {
  if (i == n) {
    int v = to_v(s);
    range(k, 2, n + 1) {
      reverse(s.begin(), s.begin() + k);
      int u = to_v(s);
      if (u != v) G.add_directed_edge(v, u, 1);
      reverse(s.begin(), s.begin() + k);
    }
    return;
  }

  for (auto c : {'A', 'B', 'C'}) {
    s += c;
    make_G(i + 1, s, n, G);
    s.pop_back();
  }
}

void solve() {
  int n = input(), q = input();

  int V = to_v(string(n, 'C')) + 2;
  int ST = V - 1;
  Graph G(V);
  string s;
  make_G(0, s, n, G); 

  range(a, 0, n + 1) range(b, 0, n + 1) range(c, 0, n + 1) {
    if (a + b + c != n) continue;
    string s = string(a, 'A') + string(b, 'B') + string(c, 'C');
    G.add_directed_edge(ST, to_v(s), 1);
  }

  auto ds = bfs(G, ST);
    
  range(qi, 0, q) {
    string s;
    cin >> s;

    int u = to_v(s);
    cout << ds[u] - 1 << endl;
  }
}

signed main() {
  solve();
}
accuracy: 1
time_ms: 1070
memory_kb: 469336
final_rank: 13