Problem:
Problem B:
Repeated Substitution with Sed
Do you know "sed," a tool provided with Unix? Its most popular use is to substitute every
occurrence of a string
contained in the input string (actually each input line) with another
string
β
. More precisely, it proceeds as follows.
Within the input string, every non-overlapping (but possibly adjacent) occurrences of
α
are
      marked. If there is more than one possibility for non-overlapping matching, the leftmost
      one is chosen.
Each of the marked occurrences is substituted with
β
to obtain the output string; other
      parts of the input string remain intact.
For example, when
α
is "
aa
" and
β
is "
bca
", an input string "
aaxaaa
" will produce "
bcaxbcaa
",
but not "
aaxbcaa
" nor "
bcaxabca
". Further application of the same substitution to the string
"
bcaxbcaa
" will result in "
bcaxbcbca
", but this is another substitution, which is counted as the
second one.
In this problem, a set of substitution pairs (
α
i
,
β
i
) (
i
= 1, 2, ... ,
n
), an initial string
γ
, and a
final string
δ
are given, and you must investigate how to produce
δ
from
γ
with a minimum
number of substitutions. A single substitution (
α
i
,
β
i
) here means simultaneously substituting
all the non-overlapping occurrences of
α
i
, in the sense described above, with
β
i
.
You may use a specific substitution (
α
i
,
β
i
) multiple times, including zero times.
Input
The input consists of multiple datasets, each in the following format.
n
α
1
β
1
α
2
β
2
.
.
.
α
n
β
n
γ
δ
n
is a positive integer indicating the number of pairs.
α
i
and
β
i
are separated by a single space.
You may assume that 1 ≤ |
α
i
| < |
β
i
| ≤ 10 for any
i
(|
s
| means the length of the string
s
),
α
i
≠
α
j
for any
i
≠
j
,
n
≤ 10 and 1 ≤ |
γ
| < |
δ
| ≤ 10. All the strings consist solely of lowercase
letters. The end of the input is indicated by a line containing a single zero.
Output
For each dataset, output the minimum number of substitutions to obtain
δ
from
γ
. If
δ
cannot
be produced from
γ
with the given set of substitutions, output
-1
.
Sample Input
2
a bb
b aa
a
bbbbbbbb
1
a aa
a
aaaaa
3
ab aab
abc aadc
ad dee
abc
deeeeeeeec
10
a abc
b bai
c acf
d bed
e abh
f fag
g abe
h bag
i aaj
j bbb
a
abacfaabe
0
Output for the Sample Input
3
-1
7
4

Submitted solutions:

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

int solve(int N){
    vc<pair<string, string>> change(N);
    rep(i, N) cin >> change[i].first >> change[i].second;
    string S, T; cin >> S >> T;
    map<string, int> dist;
    dist[S] = 0;
    dist[T] = inf;
    deque<string> q;
    q.push_back(S);
    while(!q.empty()){
        auto v = q.front(); q.pop_front();
        for (auto [a, b] : change){
            string u = "";
            int last = 0;
            for (auto x : v){
                u += x;
                if (len(u) - last >= len(a) && u.substr(len(u) - len(a)) == a){
                    rep(i, len(a)) u.pop_back();
                    u += b;
                    last = len(u);
                }
            }
            if (len(u) > len(T)) continue;
            if (!dist.count(u)) dist[u] = inf;
            if (dist[u] > dist[v] + 1){
                dist[u] = dist[v] + 1;
                q.push_back(u);
            }
        }
    }
    if (dist[T] == inf) return -1;
    return dist[T];
}

int main(){
    vi ans;
    while (true){
        int N; cin >> N;
        if (N == 0) break;
        ans.push_back(solve(N));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3616
final_rank: 8

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

bool solve() {
    int N; cin >> N;
    if (N == 0) return false;

    vector<pair<string, string>> P(N);
    for (auto& [a, b] : P) cin >> a >> b;

    auto sed = [&](string S, int i) -> string {
        const auto& [a, b] = P[i];
        reverse(S.begin(), S.end());
        string res{};
        while (S.size()) {
            if (S.size() < a.size()) {
                while (S.size()) {
                    res.push_back(S.back());
                    S.pop_back();
                }
                break;
            }
            bool match = true;
            for (int i = 0 ; i < (int)a.size() ; i++) {
                match &= S[S.size() - i - 1] == a[i];
            }
            if (match) {
                for (int i = 0 ; i < (int)a.size() ; i++) S.pop_back();
                for (int i = 0 ; i < (int)b.size() ; i++) res.push_back(b[i]);
            }
            else {
                res.push_back(S.back());
                S.pop_back();
            }
        }
        return res;
    };

    string S; cin >> S;
    string G; cin >> G;

    auto dfs = [&](auto dfs, string now) -> int {
        // cout << now << endl;
        if (now == G) return 0;
        int res = 1000100;
        if (now.size() > G.size()) return res;
        for (int i = 0 ; i < N ; i++) {
            string nxt = sed(now, i);
            if (now == nxt) continue;
            res = min(res, dfs(dfs, nxt) + 1);
        }
        return res;
    };

    int ans = dfs(dfs, S);
    cout << (ans == 1000100 ? -1 : ans) << endl;

    return true;
}

int main() {
    while (solve()) ;
}
accuracy: 1
time_ms: 10
memory_kb: 3332
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vvvvll = vector<vvvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#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 + 7;
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 (k < 0)return 0;
    if (n < k) return 0;
    return fact.at(n) * (factinv.at(k) * factinv.at(n - k) % mod) % mod;
}
namespace atcoder {

    namespace internal {

        // @param n `0 <= n`
        // @return minimum non-negative `x` s.t. `n <= 2**x`
        int ceil_pow2(int n) {
            int x = 0;
            while ((1U << x) < (unsigned int)(n)) x++;
            return x;
        }

        // @param n `1 <= n`
        // @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
        int bsf(unsigned int n) {
#ifdef _MSC_VER
            unsigned long index;
            _BitScanForward(&index, n);
            return index;
#else
            return __builtin_ctz(n);
#endif
        }

    }  // namespace internal

}  // namespace atcoder

namespace atcoder {

    template <class S,
        S(*op)(S, S),
        S(*e)(),
        class F,
        S(*mapping)(F, S),
        F(*composition)(F, F),
        F(*id)()>
        struct lazy_segtree {
        public:
            lazy_segtree() : lazy_segtree(0) {}
            lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
            lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
                log = internal::ceil_pow2(_n);
                size = 1 << log;
                d = std::vector<S>(2 * size, e());
                lz = std::vector<F>(size, id());
                for (int i = 0; i < _n; i++) d[size + i] = v[i];
                for (int i = size - 1; i >= 1; i--) {
                    update(i);
                }
            }

            void set(int p, S x) {
                //assertrt(0 <= p && p < _n);
                p += size;
                for (int i = log; i >= 1; i--) push(p >> i);
                d[p] = x;
                for (int i = 1; i <= log; i++) update(p >> i);
            }

            S get(int p) {
                //assertrt(0 <= p && p < _n);
                p += size;
                for (int i = log; i >= 1; i--) push(p >> i);
                return d[p];
            }

            S prod(int l, int r) {
                //assertrt(0 <= l && l <= r && r <= _n);
                if (l == r) return e();

                l += size;
                r += size;

                for (int i = log; i >= 1; i--) {
                    if (((l >> i) << i) != l) push(l >> i);
                    if (((r >> i) << i) != r) push(r >> i);
                }

                S sml = e(), smr = e();
                while (l < r) {
                    if (l & 1) sml = op(sml, d[l++]);
                    if (r & 1) smr = op(d[--r], smr);
                    l >>= 1;
                    r >>= 1;
                }

                return op(sml, smr);
            }

            S all_prod() { return d[1]; }

            void apply(int p, F f) {
                //assertrt(0 <= p && p < _n);
                p += size;
                for (int i = log; i >= 1; i--) push(p >> i);
                d[p] = mapping(f, d[p]);
                for (int i = 1; i <= log; i++) update(p >> i);
            }
            void apply(int l, int r, F f) {
                //assertrt(0 <= l && l <= r && r <= _n);
                if (l == r) return;

                l += size;
                r += size;

                for (int i = log; i >= 1; i--) {
                    if (((l >> i) << i) != l) push(l >> i);
                    if (((r >> i) << i) != r) push((r - 1) >> i);
                }

                {
                    int l2 = l, r2 = r;
                    while (l < r) {
                        if (l & 1) all_apply(l++, f);
                        if (r & 1) all_apply(--r, f);
                        l >>= 1;
                        r >>= 1;
                    }
                    l = l2;
                    r = r2;
                }

                for (int i = 1; i <= log; i++) {
                    if (((l >> i) << i) != l) update(l >> i);
                    if (((r >> i) << i) != r) update((r - 1) >> i);
                }
            }

            template <bool (*g)(S)> int max_right(int l) {
                return max_right(l, [](S x) { return g(x); });
            }
            template <class G> int max_right(int l, G g) {
                //assertrt(0 <= l && l <= _n);
                //assertrt(g(e()));
                if (l == _n) return _n;
                l += size;
                for (int i = log; i >= 1; i--) push(l >> i);
                S sm = e();
                do {
                    while (l % 2 == 0) l >>= 1;
                    if (!g(op(sm, d[l]))) {
                        while (l < size) {
                            push(l);
                            l = (2 * l);
                            if (g(op(sm, d[l]))) {
                                sm = op(sm, d[l]);
                                l++;
                            }
                        }
                        return l - size;
                    }
                    sm = op(sm, d[l]);
                    l++;
                } while ((l & -l) != l);
                return _n;
            }

            template <bool (*g)(S)> int min_left(int r) {
                return min_left(r, [](S x) { return g(x); });
            }
            template <class G> int min_left(int r, G g) {
                //assertrt(0 <= r && r <= _n);
                //assertrt(g(e()));
                if (r == 0) return 0;
                r += size;
                for (int i = log; i >= 1; i--) push((r - 1) >> i);
                S sm = e();
                do {
                    r--;
                    while (r > 1 && (r % 2)) r >>= 1;
                    if (!g(op(d[r], sm))) {
                        while (r < size) {
                            push(r);
                            r = (2 * r + 1);
                            if (g(op(d[r], sm))) {
                                sm = op(d[r], sm);
                                r--;
                            }
                        }
                        return r + 1 - size;
                    }
                    sm = op(d[r], sm);
                } while ((r & -r) != r);
                return 0;
            }

        private:
            int _n, size, log;
            std::vector<S> d;
            std::vector<F> lz;

            void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
            void all_apply(int k, F f) {
                d[k] = mapping(f, d[k]);
                if (k < size) lz[k] = composition(f, lz[k]);
            }
            void push(int k) {
                all_apply(2 * k, lz[k]);
                all_apply(2 * k + 1, lz[k]);
                lz[k] = id();
            }
    };

}  // 
using namespace atcoder;

struct S {
    ll a;
    int size;
};

struct F {
    ll a, b;
};

S op(S l, S r) { return S{ min(l.a,r.a), l.size + r.size }; }

S e() { return S{ ll(1e18), 0 }; }

S mapping(F l, S r) { return S{ r.a * l.a + r.size * l.b, r.size }; }

F composition(F l, F r) { return F{ r.a * l.a, r.b * l.a + l.b }; }

F id() { return F{ 1, 0 }; }

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

    while (1) {
        ll N;
        cin >> N;
        if (N == 0)return 0;
        vector<string> A(N), B(N);
        rep(i, N)cin >> A[i] >> B[i];
        string S, T;
        cin >> S >> T;
        set<string> seen;
        map<string, ll> AN;
        AN[S] = 0;
        queue<string> que;
        que.push(S);
        while (!que.empty()) {
            string p = que.front();
            que.pop();
            if (p.size() > 10)continue;
            if (seen.count(p))continue;
            seen.insert(p);
            rep(i, N) {
                string res = "";
                rep(j, p.size()) {
                    if (j+A[i].size()<=p.size()&&p.substr(j, A[i].size()) == A[i]) {
                        res = res + B[i];
                        j += A[i].size() - 1;
                    }
                    else {
                        res.push_back(p[j]);
                    }
                }
                if (!seen.count(res)) {
                    if (AN.count(res) && AN[res] <= AN[p] + 1)continue;
                    AN[res] = AN[p] + 1;
                    que.push(res);
                }
            }
        }
        cout << (seen.count(T) ? AN[T] : -1) << endl;
    }



}
accuracy: 1
time_ms: 20
memory_kb: 4300
final_rank: 16

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

int main(){
    int n;
    while(cin >> n, n){
        int ans = -1;
        vector<array<string,2>> a(n);
        for(int i = 0; i < n; i++){
            cin >> a[i][0] >> a[i][1];
        }
        string from, to;
        cin >> from >> to;
        map<string,int> mp;
        queue<string> nxt;
        mp[from] = 0;
        nxt.push(from);
        auto f = [&](string s, string t, string u){
            string res, res2;
            int tn = t.size();
            for(int i = 0; i < s.size(); i++){
                res += s[i];
                if(res.size() < tn)continue;
                if(res.substr(res.size() - tn, tn) == t){
                    for(int j = 0; j < tn; j++)res.pop_back();
                    res += u;
                    res += "{";
                }
            }
            for(int i = 0; i < res.size(); i++){
                if(res[i] == '{')continue;
                res2 += res[i];
            }
            return res2;
        };
        while(!nxt.empty()){
            string s;
            s = nxt.front();
            nxt.pop();
            if(s.size() > to.size())continue;
            int d = mp[s];
            if(s == to){
                ans = d;
                break;
            }
            for(int i = 0; i < n; i++){
                string t = f(s, a[i][0], a[i][1]);
                if(mp.find(t) == mp.end()){
                    mp[t] = d + 1;
                    nxt.push(t);
                }
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3872
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	
	while(true) {
		int n; cin >> n; if(n == 0) break;
		vector<string> a(n), b(n);
		rep(i,n) cin >> a[i] >> b[i];
		string c, d; cin >> c >> d;

		map<string,int> mp;
		mp[c] = 0;
		queue<string> q;
		q.push(c);

		while(!q.empty()) {
			string v = q.front(); q.pop();
			rep(i,n) {
				string to = "";
				rep(j,v.size()) {
					if(j <= v.size() - a[i].size()) {
						if(v.substr(j, a[i].size()) == a[i]) {
							to += b[i];
							j += a[i].size() - 1;
						} else {
							to += v[j];
						}
					} else {
						to += v[j];
					}
				}

				if(!mp.count(to) && to.size() <= d.size()) {
					mp[to] = mp[v] + 1;
					q.push(to);
				}
			}
		}

		cout << (mp.count(d) ? mp[d] : -1) << '\n';
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3384
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#include <regex>
using namespace std;
const int INF = 1e9;
#define keta(n, x) cout << fixed << setprecision((int)n) << (double)x << endl;

int BFS(int n){
    vector<pair<string, string>> S(n);
    set<string> check;
    int ans = -1;
    for(int i = 0; i < n; i++){
        string a, b;
        cin >> a >> b;
        S[i] = make_pair(a, b);
    }
    string g, d;
    cin >> g >> d;
    queue<string> que;
    que.push(g); //初期状態
    check.insert(g);
    map<string, int> cnt; //置換回数
    cnt[g] = 0;
    int fin_size = d.size();

    bool ok = false;
    while(!que.empty()){
        //queの先頭を取り出す．
        string T = que.front();
        que.pop();

        //文字列の置換パート
        string old_T = T;
        for(int i = 0; i < n; i++){
            //文字列の置換
            string new_T = regex_replace(old_T, regex(S[i].first), S[i].second);
            //常に置換済みであればキューに入れない．
            if(!check.count(new_T)){
                check.insert(new_T);
                if(new_T == d) ok = true;
                //文字列の長さがターゲットより大きければ入れない
                if(new_T.size() <= fin_size){
                    que.push(new_T);
                }else{
                    continue;
                }
            }else{
                continue;
            }
            if(!cnt.count(new_T)) cnt[new_T] = cnt[old_T] + 1;
        }
    }
    if(ok){
        return cnt[d];
    }else{
        return -1;
    }
} 

int main(){
    while(1){   
       int n;
       cin >> n;
       if(n == 0) break;
        cout << BFS(n) << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 4244
final_rank: 18

code_snippet: #include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <bitset>
#include <vector>
#include <queue>
#include <set>

using namespace std;

typedef long long ll;
#define FOR(i,a,b)  for(ll i = (a); i < (b); i++ )
#define REP(i, n)   FOR(i,0,n)
typedef pair< ll, ll >   cp2;
typedef pair< string, cp2 >   cp3;
typedef pair< int, string > pis;
#define fi first
#define se second
#define sec  se.fi
#define thr  se.se
#define V_MAX 112345
const ll mod = 998244353;
//             123456789

int N;
string S;
string T;
string X, Y;

pair< string, string > A[11];
pis tmp;
priority_queue< pis, vector<pis>, greater<pis> > pq;

int main(){
    
    cin>>N;
    while( N ){
        while( !pq.empty() ) pq.pop();
        bool f = true;
        REP( i, N ){
            cin>>X>>Y;
            A[i] = make_pair( X, Y );
        }
        cin>>S>>T;
        tmp = make_pair( 0, S );
        pq.push( tmp );
        while( !pq.empty() ){
            tmp = pq.top();
            string tmpS = tmp.se;
            pq.pop();
            if( tmpS == T ){
                cout<<tmp.fi<<endl;
                f = false;
                break;
            }
            if( tmpS.size() > T.size() ) continue;
            REP( i, N ){
                string B = tmpS;
                string::size_type pos = B.find( A[i].fi );
                while( pos != string::npos ){
                    B.replace( pos, A[i].fi.size(), A[i].se );
                    pos = B.find( A[i].fi, pos+A[i].se.size() );
                }
                if( B != tmpS ) pq.push( make_pair(tmp.fi+1, B));
            }
        }
        if( f ) puts("-1");
        cin>>N;
    }
    
    
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3724
final_rank: 9

code_snippet: //#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;
// using mint = modint1000000007;
using ll = long long;
const int MOD = (int)1e9 + 7;
const int INF = (int)1e9 + 1001010;
const ll llINF = (ll)1e18 + 11000010;
const double PI = 3.14159265358979;
#define ALL(x) x.begin(),x.goal()
#define RALL(x) x.rbegin(),x.rend()
#define endn "\n"

vector<string> a, b;
vector<int> d;
string start, goal;

template <typename T>
bool chmax(T &a, const T &b){
    if(a < b) a = b;
    return a < b;
}

template <typename T>
bool chmin(T &a, const T &b){
    if(a > b) a = b;
    return a > b;
}

string my_replace(string tg, string rep_from, string rep_to){
    int head = 0;
    
    while(tg.find(rep_from, head) != string::npos){
        int fi = tg.find(rep_from, head);
        tg.replace(fi, rep_from.size(), rep_to);
        head = rep_to.size() + fi;
    }
    return tg;
}


int dfs(string st, int count){
    // base case
    if(st == goal) return count;

    // recursion step
    int ret = INF;
    for(int i = 0; i < a.size(); i++){
        if(st.find(a[i]) != string::npos){
            string r = my_replace(st, a[i], b[i]);
            if(r.size() <= goal.size()){
                chmin(ret, dfs(r, count + 1));
            }
        }
    }

    return ret;
}

int main(){
    while(true){
        int n; cin >> n;
        if(n == 0) break;

        a.resize(n);
        b.resize(n);
        d.resize(n);
        for(int i = 0; i < n; i++) cin >> a[i] >> b[i];
        for(int i = 0; i < n; i++) d[i] = (int)b[i].size() - (int)a[i].size();

        cin >> start >> goal;

        int ans = dfs(start, 0);
        if(ans == INF) ans = -1;
        cout << ans << endn;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3368
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define ll long long
#define pp pair<ll,ll>
#define ld long double
#define all(a) (a).begin(),(a).end()
#define mk make_pair
#define difine define
constexpr int inf=1000001000;
constexpr ll INF=2e18;
constexpr ll MOD=1000000007;
constexpr ll mod=998244353;
int dx[4]={1,-1,-1,1},dy[4]={1,-1,1,-1};

 
// #include <atcoder/all>
// typedef atcoder::modint1000000007 mint;
// typedef atcoder::modint998244353 mint;

int main() {
    while(true){
        int n;
        cin >> n;
        if (n==0) break;
        vector<string> a(n),b(n);
        rep(i,n) cin >> a[i] >> b[i];
        string s,t;
        cin >> s >> t;
        queue<pair<string,int>> q;
        q.push({s,0});
        int mi=inf;
        set<string> se;
        se.insert(s);
        while(!q.empty()){
            auto [f,g]=q.front();
            // cout << f << endl;
            q.pop();
            rep(i,n){
                int j=0;
                string ans;
                while(true){
                    if (j+a[i].size()>f.size()){
                        for (int k=j;k<f.size();k++) ans.push_back(f[k]);
                        break;
                    }
                    bool t=true;
                    rep(k,a[i].size()){
                        if (f[j+k]!=a[i][k]) t=false;
                    }
                    if (t){
                        ans=ans+b[i];
                        j+=a[i].size();
                    }
                    else{
                        ans.push_back(f[j]);
                        j++;
                    }
                }
                if (ans==t) mi=min(mi,g+1);
                else if (se.find(ans)==se.end() && ans.size()<=10){
                    se.insert(ans);
                    q.push({ans,g+1});
                }
            }
        }
        if (mi==inf) cout << -1 << endl;
        else cout << mi << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3520
final_rank: 5

code_snippet: #define _GLIBCXX_DEBUG // test only

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

#define INF 1020304050

int main() {
  
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  int n;
  cin >> n;
  while (n != 0) {
		vector<string> a(n),b(n);
		vector<int> alen(n);
		for (int i=0;i<n;i++) {
			cin >> a[i] >> b[i];
			alen[i] = a[i].size();
		}
		string s,g;
		cin >> s >> g;
		queue<string> q;
		q.push(s);
		map<string,int> mp;
		mp[s] = 1;
		while (!q.empty()) {
			string now = q.front();
			int sz = now.size();
			q.pop();
			for (int i=0;i<n;i++) {
				string to = "";
				int j = 0;
				while (j <= sz-alen[i]) {
					if (now.substr(j,alen[i]) == a[i]) {
						to += b[i];
						j += alen[i];
					}
					else if (j < now.size()) {
						to += now[j];
						j++;
					}
					else break;
				}
				while (j < sz) {
					to += now[j];
					j++;
				}
				if (to == now) continue;
				if (mp[to] == 0) {
					mp[to] = mp[now]+1;
				}
				if (to.size() >= g.size()) continue;
				q.push(to);
			}
		}
		cout << mp[g]-1 << endl;
    cin >> n;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3500
final_rank: 4

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

string sed(string &u, string &a, string &b) {
  string res = "";
  for (int i = 0; i < u.size(); i++) {
    if (i + a.size() > u.size()) {
      res += u[i];
      continue;
    }
    if (u.substr(i, a.size()) == a) {
      res += b;
      i += a.size() - 1;
    }
    else {
      res += u[i];
    }
  }
  return res;
}

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

  while (true) {
    int n;
    cin >> n;

    if (n == 0) return 0;

    vector<string> a(n), b(n);
    for (int i = 0; i < n; i++) cin >> a.at(i) >> b.at(i);

    string s, t;
    cin >> s >> t;

    int ans = 1e9;
    queue<pair<string, int>> q;
    q.push(make_pair(s, 0));
    while (!q.empty()) {
      auto [u, d] = q.front();
      q.pop();
      if (u.size() > t.size()) continue;
      if (u == t) {
        ans = d;
        break;
      }
      for (int i = 0; i < n; i++) {
        string u2 = sed(u, a.at(i), b.at(i));
        if (u2 == u) continue;
        //cout << u2 << endl;
        q.push(make_pair(u2, d + 1));
      }
    }

    if (ans == 1e9) cout << -1 << '\n';
    else cout << ans << '\n';
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3832
final_rank: 12

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

int main() {
    int N;
    while (cin >> N, N) {
        vector<pair<string, string>> V(N);
        for (auto&& [a, b] : V) {
            cin >> a >> b;
        }
        string S, T;
        cin >> S >> T;
        queue<pair<int, string>> que;
        que.push({0, S});
        map<string, int> maine;
        maine[S] = 0;
        while (!que.empty()) {
            auto [n, S] = que.front();
            que.pop();
            if (S == T)
                break;
            if (S.size() > T.size())
                continue;
            for (auto&& [a, b] : V) {
                string U = regex_replace(S, regex(a), b);
                if (U != S && !maine.count(U)) {
                    maine[U] = n + 1;
                    que.push({n + 1, U});
                }
            }
        }
        cout << (maine.count(T) ? maine[T] : -1) << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 4072
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using P = pair<string,string>;
map<string,int> s;
int ans = -1;

string process(P &p, string S){
  auto[x,y] = p;
  string ret = "";
  int pos = 0;
  while(pos < S.size()){
    if(pos + x.size() > S.size()){
      ret += S[pos];
      pos++;
    }
    else if(S.substr(pos,x.size()) == x){
      ret += y;
      pos += x.size();
    }
    else{
      ret += S[pos];
      pos++;
    }
  }
  return ret;
}

void dfs(vector<P> &vec, string S, string &T, int c){
  for(int i=0; i<vec.size(); i++){
    string t = process(vec[i],S);
    if(t == T){
      if(ans == -1){
        ans = c+1;
      }
      ans = min(ans,c+1);
    }
    if(!s.count(t) && T.size() > t.size()){
      s[t] = c+1;
      dfs(vec,t,T,c+1);
    }
    else if(s[t] > c+1 && T.size() > t.size()){
      s[t] = c+1;
      dfs(vec,t,T,c+1);
    }
  }
}

void solve(int N){
  vector<P> vec(N);
  s.clear();
  ans = -1;
  for(int i=0; i<N; i++){
    string a, b;
    cin >> a >> b;
    vec[i] = P(a,b);
  }
  string S, T;
  cin >> S >> T;
  dfs(vec,S,T,0);
  cout << ans << endl;
}

int main(){
  while(true){
    int N;
    cin >> N;
    if(N == 0){
      break;
    }
    solve(N);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3552
final_rank: 6

code_snippet: #include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
#include <assert.h>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ld long double
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define fcin ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
//eodefine
using namespace std;

const int max_n = 103002;
map<string,string> mp;
map<string,int> memo;

void dfs(string a,string b,int cost){
	int n=sz(a),m=sz(b);
	if(n>m) return;
	if(memo.find(a)!=memo.end() and memo[a]<cost) return;
	memo[a]=cost;

	for(auto [x,y] : mp){
		int sznow=sz(x);
		vi usd(n,0);
		for(int i=0;i<n;i++){
			if(a.substr(i,sznow)==x){
				usd[i]=1;
				i+=sznow-1;
			}
		}
		string now="";
		for(int i=0;i<n;i++){
			if(usd[i]){
				now+=y;
				i+=sznow-1;
			}else{
				now+=a[i];
			}
		}
		dfs(now,b,cost+1);
	}
	// return;
}

void slv(int n){
	string s;
	getline(cin,s);

	mp.clear();
	memo.clear();
	
	rep(i,n){
		getline(cin,s);	
		
		int spc=s.find(' ');
		if(spc==-1){
			mp[s]="";
		}else{
			mp[s.substr(0,spc)]=s.substr(spc+1);
		}
	}
	
	string a,b;
	cin>>a>>b;

	dfs(a,b,0);

	if(memo.find(b)!=memo.end()){
		cout<<memo[b]<<"\n";
	}else{
		cout<<"-1\n";
	}

}

int main(){
fcin;
	while(true){
		int n;
		cin>>n;
		if(!n)break;
		slv(n);
	}
/*
*/
    return 0;   
}
accuracy: 1
time_ms: 40
memory_kb: 3532
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); ++i)
const int INF = 30;

string Replace(const string &str, const string &a, const string &b) {
    string res = "";
    for(int i = 0; i < str.size(); ++i) {
        if(str.substr(i, a.size()) == a) {
            res += b;
            i += a.size() - 1;
        } else {
            res += str[i];
        }
    }
    return res;
}

bool solve() {
    int n; cin >> n;
    if(n == 0) return false;
    vector<pair<string, string>> sub(n);
    for(auto &[a, b] : sub) cin >> a >> b;
    string bef, aft;
    cin >> bef >> aft;

    auto f = [&](auto &&f, string s, int x) -> int {
        if(s.size() > aft.size()) return INF;
        if(s == aft) return x;
        int res = INF;
        for(auto &[a, b] : sub) {
            if(s == Replace(s, a, b)) continue;
            res = min(res, f(f, Replace(s, a, b), x + 1));
        }
        return res;
    };

    int ans = f(f, bef, 0);
    if(ans == INF) ans = -1;
    cout << ans << '\n';
    return true;
}

int main() {
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3376
final_rank: 10

code_snippet: #include <iostream>
#include <queue>
#include <map>
using namespace std;

void transform(string &s, string &a, string &b){
    int i = 0;
    while(true){
        if(i + (int)a.size() > (int)s.size()) return;
        if(s.substr(i, (int)a.size()) == a){
            s = s.substr(0, i) + b + s.substr(i + (int)a.size());
            i += (int)b.size();
        }
        else i++;
    }
}

int main()
{
    while(true){
        int n;
        cin >> n;
        if(n == 0) break;
        string a[12], b[12];
        for(int i = 0; i < n; i++) cin >> a[i] >> b[i];
        string c, d;
        cin >> c >> d;
        map<string, int> mp;
        queue<string> que;
        mp[c] = 0;
        que.push(c);
        while(que.size()){
            string s = que.front();
            que.pop();
            if((int)s.size() > 10) continue;
            for(int i = 0; i < n; i++){
                string t = s;
                transform(t, a[i], b[i]);
                if(!mp.count(t)){
                    mp[t] = mp[s] + 1;
                    que.push(t);
                }
            }
        }
        if(!mp.count(d)) cout << -1 << endl;
        else cout << mp[d] << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 4096
final_rank: 17

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

int solve() {
    int n;
    cin >> n;
    if (n == 0) return 1;
    vector<string> a(n), b(n);
    for (int i = 0; i < n; ++i) cin >> a[i] >> b[i];
    string s, t;
    cin >> s >> t;

    set<string> st;
    auto dfs = [&](auto self, string now, int time) -> int {
        st.insert(now);
        if (now.size() == t.size()) return now == t ? time : INT_MAX;
        int res = INT_MAX;
        for (int i = 0; i < n; ++i) {
            string nxt = regex_replace(now, regex(a[i]), b[i]);
            if (nxt.size() <= t.size() && !st.count(nxt)) res = min(res, self(self, nxt, time + 1));
        }
        return res;
    };

    int ans = dfs(dfs, s, 0);
    cout << (ans == INT_MAX ? -1 : ans) << '\n';

    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 10
memory_kb: 3312
final_rank: 1

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-11, PI = acos(-1);
//ここから編集

class KMP
{
public:
  string p;
  int plen;
  vector<int> mp;
  vector<int> kmp;
 
  /* MPとKMPの構築 計算量O(logN) */
  KMP(string s) : p(s), plen((int)p.size()), mp(plen + 1), kmp(plen + 1)
  {
    mp[0] = kmp[0] = -1;
    int j = -1;
    for (int i = 0; i < plen; i++)
    {
      while (j >= 0 && p[i] != p[j])
        j = kmp[j];
 
      kmp[i + 1] = mp[i + 1] = ++j;
 
      if (i + 1 < plen && p[i + 1] == p[j])
        kmp[i + 1] = kmp[j];
    }
  }
 
  //文字列patternのS[0~i]の最小の周期長を求める
  //計算量:O(N)
  vector<ll> cycle()
  {
    vector<ll> res(plen);
    for (int i = 0; i < plen; i++)
    {
      res[i] = i - kmp[i];
    }
    return res;
  }
 
  /* MPを使った文字列検索 */
  vector<ll> search(string &text)
  {
    vector<ll> res;
    int i, j;
    int tlen = text.size();
 
    i = j = 0;
    while (j < tlen)
    {
      while (i > -1 && p[i] != text[j])
        i = kmp[i];
 
      i++;
      j++;
      if (i >= plen)
      {
        res.push_back(j - i);
        i = kmp[i];
      }
    }
    return res;
  }
};


int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  
  int n;
  while(cin >> n, n){
    vector<string> a(n), b(n);
    REP(i,n){
      cin >> a[i] >> b[i];
    }

    string s, g; cin >> s >> g;

    map<string, int> dist;
    dist[s] = 0;
    priority_queue<pair<int, string>, vector<pair<int, string>>, greater<pair<int, string>>> q;
    q.push({0, s});
    while(q.size()){
      auto p = q.top();
      q.pop();
      
      int v = p.first;
      string w = p.second;

      if(w.size() > 10) continue;
      
      for(int i=0; i<n; i++){
        
        string nx = "";
        KMP kmp(a[i]);
          
        auto ret = kmp.search(w);
        vector<bool> used(w.size());

        if(ret.size() == 0) continue;
        REP(i,ret.size()) used[ret[i]] = true;
        int idx = 0;
        for(int j=0; j<w.size(); j++){
          if(used[j]){
            nx += b[i];
            j += (int)a[i].size()-1;
            idx++;
          }else{
            nx += w[j];
          }
        }
        //cout << nx << endl;
        if(w != nx){
          if(dist.find(nx) == dist.end()){
            dist[nx] = dist[w] + 1;
            q.push({dist[nx], nx});
          }
        }
      }
    }
    if(dist.find(g) == dist.end()) cout << -1 << endl;
    else cout << dist[g] << endl;

  }

  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 4144
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)

string sed(string s, string before, string after)
{
    string ret = "";
    int i = 0;
    while (i < s.size()) {
        if (i + before.size() > s.size()) {
            ret += s[i];
            i++;
        } else if (s.substr(i, before.size()) == before) {
            ret += after;
            i += before.size();
        } else {
            ret += s[i];
            i++;
        }
    }
    return ret;
}

void solve(int n)
{
    vector<string> before(n), after(n);
    rep(i, n) cin >> before[i] >> after[i];
    string s, t;
    cin >> s >> t;
    deque<string> que;
    que.push_back(s);
    int ans = 0;
    while (!que.empty()) {
        deque<string> next;
        while (!que.empty()) {
            string cur = que.front();
            que.pop_front();
            if (cur == t) {
                cout << ans << endl;
                return;
            }
            if (cur.size() > t.size())
                continue;
            rep(i, n)
            {
                string ncur = sed(cur, before[i], after[i]);
                if (cur != ncur) {
                    next.push_back(ncur);
                }
            }
        }
        que = next;
        ans++;
    }
    cout << -1 << endl;
    return;
}

int main()
{
    int n;
    while (cin >> n, n) {
        solve(n);
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4324
final_rank: 19

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

void solve(int n){
    vector<string> a(n),b(n);
    for (int i=0;i<n;++i) cin >> a[i] >> b[i];
    string s,t; cin >> s >> t;

    auto substitute=[&](string S,int x){
        string res="";
        int l=a[x].size();
        for (int i=0;i<S.size();++i){
            if (i+l<=S.size()&&S.substr(i,l)==a[x]){
                res+=b[x]; i+=l-1;
            } else res+=S[i];
        }
        return res;
    };
    unordered_map<string,int> dp;
    priority_queue<pair<int,string>> pq;
    dp[s]=0; pq.emplace(-dp[s],s);
    while(!pq.empty()){
        auto p=pq.top(); pq.pop();
        string S=p.second;
        if (dp[S]<-p.first) continue;
        if (S.size()>=t.size()) continue;
        for (int i=0;i<n;++i){
            string nxt=substitute(S,i);
            if (!dp.count(nxt)||dp[S]+1<dp[nxt]){
                dp[nxt]=dp[S]+1;
                pq.emplace(-dp[nxt],nxt);
            }
        }
    }

    cout << (dp.count(t)?dp[t]:-1) << '\n';
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    while(cin >> n,n){
        solve(n);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3560
final_rank: 7