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

int findMinChanges(string& a, string& b, string& c) {
    int len_a = a.size(), len_b = b.size(), len_c = c.size();
    if (len_a + len_b != len_c) return -1;
    vector<vector<int>> dp(len_a + 1, vector<int>(len_b + 1, INT_MAX));
    dp[0][0] = 0;
    for (int s1 = 0; s1 <= len_a; ++s1) {
        for (int s2 = 0; s2 <= len_b; ++s2) {
            int s3 = s1 + s2;
            if (s3 > len_c) break;
            if (s1 < len_a && s3 < len_c) {
                dp[s1 + 1][s2] = min(dp[s1 + 1][s2], dp[s1][s2] + (a[s1] != c[s3]));
            }
            if (s2 < len_b && s3 < len_c) {
                dp[s1][s2 + 1] = min(dp[s1][s2 + 1], dp[s1][s2] + (b[s2] != c[s3]));
            }
        }
    }

    return dp[len_a][len_b];
}

void solve() {
    int t;cin>>t;
    while(t--){
        string a, b, c;
    cin >> a >> b >> c;

    int result = findMinChanges(a, b, c);
    if (result == -1) {
        cout << "Impossible to merge" << endl;
    } else {
        cout << result << endl;
    }
    }
}
int main(){
    solve();
}

// Every problem you solve is a step closer to mastering
// the art of thinking. Embrace the challenge,
// because every failure is just a lesson on your way to victory

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

// #include <ext/pb_ds/hash_policy.hpp> // For hash policy
#include <cmath> // For acos

using namespace std;
// using namespace __gnu_pbds; // For policy-based data structures
using ll = long long; // Type alias for long long
#define int long long
#define db double
#define MOP 998244353
#define N 2e5 + 5
#define fr(i, a, b) for (int i = a; i >= b; i--)
#define lcm(a, b) ((a) * (b)) / __gcd(a, b)
#define inp(a, n)               \
    for (int r = 0; r < n; r++) \
    cin >> a[r]
#define out(a, n)               \
    for (int v = 0; v < n; v++) \
    cout << a[v] << " "
#define f(i, a, b) for (ll i = a; i <= b; i++)
#define u(a, b) for (int i = 0; i < a; i++)
#define s(v) sort(v.begin(), v.end())
#define sr(v) sort(v.end(), v.begin())
#define MOD 1000000007
#define ci(n) cin >> n
#define co(n) cout << n << " "
#define si(v) v.size()
#define py cout << "YES" << " "
#define pn cout << "NO" << " "
#define F first
#define ld long double
#define S second
#define pb(v, x) v.push_back(x)
#define pob(v) v.pop_back()
#define rev(v) reverse(v.begin(), v.end())
#define revn(v) reverse(v.end(), v.begin())
#define d_r(v) v.erase(unique(v.begin(), v.end()), v.end());
#define en cout << endl
#define all(v) v.begin(), v.end()
#define len(str) str.length()
#define each(it, m) for (auto &it : m)
#define y_n(ans)       \
    if (ans)           \
    {                  \
        cout << "YES"; \
    }                  \
    else               \
    {                  \
        cout << "NO";  \
    }
#include <functional>
#include <utility>
#ifdef DEBUG
#define dbg(...) __VA_ARGS__
#else
#define dbg(...)
#endif
#define llmin LLONG_MIN
#define llmax LLONG_MAX
template <typename F>
struct y_combinator_result
{
    F fi;
    template <typename... Args>
    decltype(auto) operator()(Args &&...args) const
    {
        return fi(*this, std::forward<Args>(args)...);
    }
};
template <typename F>
decltype(auto) y_combinator(F &&fi)
{
    return y_combinator_result<std::decay_t<F>>{std::forward<F>(fi)};
}
template <typename T>
using V = vector<T>;
template <typename T1, typename T2>
using P = pair<T1, T2>;
template <typename T>
using pqmax = priority_queue<T>;
template <typename T>
using pqmin = priority_queue<T, vector<T>, greater<T>>;
template <typename K, typename V>
using UMP = unordered_map<K, V>;
template <typename K, typename V>
using MP = map<K, V>;
template <typename T>
using SE = set<T>;
template <typename T>
using USE = unordered_set<T>;
struct pair_hash
{
    template <class T1, class T2>
    std::size_t operator()(const std::pair<T1, T2> &pair) const
    {
        return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
    }
};
ll add(ll a, ll b, ll MO) { return ((a % MO + b % MO) % MO); }
long long factorialDP(ll n)
{
    vector<long long> dp(n + 1, 1);
    for (ll i = 2; i <= n; ++i)
    {
        dp[i] = (1LL * dp[i - 1] * i) % MOD;
    }
    return (dp[n]);
}
bool binary(vector<int> &v, int i, int j, int k)
{
    if (i >= j)
    {
        return false;
    }
    int mid = (i + j) / 2;
    bool a = false, b = false;
    if (v[i] == k || v[j] == k || v[mid] == k)
    {
        return true;
    }
    if (v[mid] < k)
    {
        a = binary(v, mid + 1, j, k);
    }
    if (v[mid] > k)
    {
        b = binary(v, i, mid, k);
    }
    return a || b;
}
int ternarySearch(vector<int> &v, int left, int right, int key) { return (right >= left) ? ((v[left + (right - left) / 3] == key) ? left + (right - left) / 3 : ((v[right - (right - left) / 3] == key) ? right - (right - left) / 3 : ((key < v[left + (right - left) / 3]) ? ternarySearch(v, left, left + (right - left) / 3 - 1, key) : ((key > v[right - (right - left) / 3]) ? ternarySearch(v, right - (right - left) / 3 + 1, right, key) : ternarySearch(v, left + (right - left) / 3 + 1, right - (right - left) / 3 - 1, key))))) : -1; }
bool palindrome(vector<int> &v)
{
    return (v.size() == 1) ? true : [&]()
    { int x = v.size() / 2; for (int t = 0; t < x; t++) { if (v[t] != v[v.size() - t - 1]) return false; } return true; }();
}
int xor_from_1(int n) { return ((n % 4 == 0) ? n : (n % 4 == 1) ? 1
                                               : (n % 4 == 2)   ? n + 1
                                                                : 0); }
void subsets(vector<ll> &v, int n)
{
    for (int i = 0; i < (1 << n); i++)
    {
        vector<ll> ans;
        for (int j = 0; j < n; j++)
            if (i & (1 << j))
                ans.push_back(v[j]);
        for (auto it : ans)
            cout << it << " ";
        cout << endl;
    }
}
string binary_rep(int n)
{
    if (n == 0)
    {
        return "0";
    }
    bitset<128> binary(n);
    string ans = "";
    for (size_t g = 0; g < 64; g++)
        ans += binary[g] + '0';
    rev(ans);
    size_t it = ans.find_first_not_of('0');
    return ans.substr(it);
}
int search(vector<ll> &v, ll target)
{
    int low = 0, high = v.size() - 1;
    while (low <= high)
    {
        int mid = low + (high - low) / 2;
        if (v[mid] < target && v[mid + 1] > target)
            return v[mid];
        if (v[mid] < target)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return high;
}
ll max_len_string(string str)
{
    ll len = 1, ans = 1;
    ll n = str.length();
    f(i, 1, n - 1)
    {
        if (str[i] >= str[i - 1])
            len++;
        else
        {
            ans = max(ans, len);
            len = 1;
        }
        ans = max(ans, len);
    }
    return ans;
}
void dfs(string str, vector<int> &dp, unordered_map<int, list<int>> &m, int n, unordered_map<int, bool> &visited, int node)
{
    visited[node] = 1;
    if (si(m[node]) == 0)
    {
        dp[node] = ((str[node - 1] == 'W') ? 1 : -1);
        return;
    }
    for (auto it : m[node])
    {
        if (!visited[it])
        {
            dfs(str, dp, m, n, visited, it);
            dp[node] += dp[it];
        }
    }
    dp[node] += ((str[node - 1] == 'W') ? 1 : -1);
}
ll nextint(ll a, ll b)
{
    ll x = ceil(((double)a) / (double)b);
    return x;
}
void sieveOfEratosthenes(int n, vector<bool> &prime)
{
    prime[0] = prime[1] = false;
    for (int p = 2; p * p <= n; p++)
        if (prime[p])
            for (int i = p * p; i <= n; i += p)
                prime[i] = false;
}
long long largestPrimeFactor(long long n)
{
    long long largest = -1;
    while (n % 2 == 0)
    {
        largest = 2;
        n /= 2;
    }
    for (long long i = 3; i <= sqrt(n); i += 2)
    {
        while (n % i == 0)
        {
            largest = i;
            n /= i;
        }
    }
    if (n > 2)
    {
        largest = n;
    }
    return largest;
}
bool isPalindrome(const std::string &str) { return std::equal(str.begin(), str.begin() + str.size() / 2, str.rbegin()); }
// #pragma once
// struct chash { // large odd number for C
// 	const uint64_t C = (long long)(4e18 * acos(0)) | 71;
// 	ll operator()(ll x) const { return __builtin_bswap64(x*C); }
// };
// __gnu_pbds::gp_hash_table<ll,int,chash> h({},{},{},{},{1<<16});
struct custom_hash
{
    static uint64_t splitmix64(uint64_t x)
    {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const
    {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
    template <class T1, class T2>
    size_t operator()(const pair<T1, T2> &p) const
    {
        auto h1 = (*this)(static_cast<uint64_t>(p.first));
        auto h2 = (*this)(static_cast<uint64_t>(p.second));
        return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
    }
    template <class T>
    size_t operator()(const vector<T> &v) const
    {
        size_t seed = v.size();
        for (auto &i : v)
        {
            seed ^= (*this)(static_cast<uint64_t>(i)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        }
        return seed;
    }
};
long long countseti(long long n, int i)
{
    long long power = 1LL << i;
    long long complete_blocks = (n + 1) / (2 * power);
    long long remainder = (n + 1) % (2 * power);
    long long count_set = complete_blocks * power + max(0LL, remainder - power);
    return count_set;
}
ll getor(const ll L, const ll R)
{
    ll ans = 0;
    y_combinator([&](const auto &self, const ll l, const ll r) -> void
                 {
        if(r<L||R<l)
            return;
        if(L<=l&&r<=R){
            ans|=r;
            return;
        }
        const ll m=(l+r)/2;
        self(l,m);
        self(m+1,r); })(0, (1LL << 60) - 1);
    return ans;
}
struct hash_pair
{
    template <class T1, class T2>
    size_t operator()(const pair<T1, T2> &p) const
    {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);
        return hash1 ^ hash2;
    }
};
bool prime(int n)
{
    if (n <= 1)
        return false;
    if (n <= 3)
        return true;
    if (n % 2 == 0 || n % 3 == 0)
        return false;
    for (int i = 5; i <= sqrt(n); i += 6)
    {
        if (n % i == 0 || n % (i + 2) == 0)
            return false;
    }
    return true;
}
int VAL;
int arr[(unsigned long)N];
struct Query
{
    int l, r;
    int id;
    bool operator<(const Query &other)
    {
        if (l / VAL == other.l / VAL)
            return r < other.r;
        return l / VAL < other.l / VAL;
    }
};
vector<Query> queries;
class Mo_Algorithm
{
private:
    vector<ll> ans;   // answer for each queries
    vector<int> freq; // frequency of values
    int cur_l, cur_r; // current left and right
    ll cur_res;       // current result

    Mo_Algorithm() = default;

    void add(int x)
    {
        /*
        Every time we add x
        freq[x] * freq[x] * x will become (freq[x] + 1) * (freq[x] + 1) * x
        Let's subtract the latters by the formers, we have 2 * freq[x] * x + x

        similar for remove function
        */
        cur_res += 2ll * freq[x] * x + x;
        freq[x]++;
    }

    void remove(int x)
    {
        cur_res -= 2ll * freq[x] * x - x;
        freq[x]--;
    }

    void convert(int l, int r, int id, int *arr)
    {
        // shifting cur_l and cur_r to the right position cur_l -> l, cur_r -> r
        while (cur_l < l)
        {
            remove(arr[cur_l]);
            cur_l++;
        }
        while (cur_r < r)
        {
            cur_r++;
            add(arr[cur_r]);
        }
        while (cur_l > l)
        {
            cur_l--;
            add(arr[cur_l]);
        }
        while (cur_r > r)
        {
            remove(arr[cur_r]);
            cur_r--;
        }

        // update result
        ans[id] = cur_res;
    }

public:
    Mo_Algorithm(int l, int r) : cur_l(l), cur_r(r)
    {
        cur_res = 0;
        ans.resize(2e5, 0ll);
        freq.resize(1e6 + 5, 0);
    }

    void process(Query q, int *arr)
    {
        convert(q.l, q.r, q.id, arr);
    }

    void print(int n)
    {
        for (int i = 0; i < n; i++)
            cout << ans[i] << '\n';
    }
};

int KMP(const string &pattern, const string &text)
{
    int m = len(pattern);
    int j = 0;
    V<int> prefix(m, 0);
    f(i, 1, m - 1)
    {
        while (j > 0 && pattern[j] != pattern[i])
        {
            j = prefix[j - 1];
        }
        if (pattern[i] == pattern[j])
        {
            j++;
        }
        prefix[i] = j;
    }
    int n = len(text);
    j = 0;
    for (int i = 0; i < n; i++)
    {
        while (j > 0 && text[i] != pattern[j])
        {
            j = prefix[j - 1];
        }
        if (text[i] == pattern[j])
        {
            j++;
        }
        if (j == m)
        {
            // cout << "Pattern found at index " << i - m + 1 << endl;
            j = prefix[j - 1];
            return 1;
        }
    }
    return 0;
}
int nCr(int n, int m)
{
    int a = factorialDP(n);
    int b = factorialDP(n - m);
    int c = factorialDP(m);
    int k = b * c;
    int ans = a / k;
    return ans;
}
class SegmentTree
{
private:
    vector<int> tree;
    int n;
    void build(int node, int start, int end, int value, V<int> &v)
    {
        if (start == end)
        {
            tree[node] = v[start];
        }
        else
        {
            int mid = (start + end) / 2;
            build(2 * node, start, mid, 0, v);
            build(2 * node + 1, mid + 1, end, 0, v);
            tree[node] = max(tree[2 * node], tree[2 * node + 1]);
        }
    }
    void update(int node, int start, int end, int idx, int value, V<int> &v)
    {
        if (start == end)
        {
            tree[node]++;
        }
        else
        {
            int mid = (start + end) / 2;
            if (start <= idx && idx <= mid)
            {
                update(2 * node, start, mid, idx, value, v);
            }
            else
            {
                update(2 * node + 1, mid + 1, end, idx, value, v);
            }
            tree[node] = max(tree[2 * node], tree[2 * node + 1]);
        }
    }
    int query(int node, int start, int end, int L, int R)
    {
        if (R < start || end < L)
        {
            return INT_MIN;
        }
        if (L <= start && end <= R)
        {
            return tree[node];
        }
        int mid = (start + end) / 2;
        int leftQuery = query(2 * node, start, mid, L, R);
        int rightQuery = query(2 * node + 1, mid + 1, end, L, R);
        return max(leftQuery, rightQuery);
    }

public:
    SegmentTree(vector<int> &arr)
    {
        n = arr.size();
        tree.resize(4 * n);
        build(1, 0, n - 1, 0, arr);
    }
    void update(int l, int r)
    {
        update(l, r);
    }
    int queryma(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }
};
class DSU
{
    vector<int> parent, rank, size;

public:
    DSU(int n) : parent(n + 1), rank(n + 1, 0), size(n + 1, 1)
    {
        for (int i = 0; i <= n; ++i)
        {
            parent[i] = i;
        }
    }
    int find(int node)
    {
        if (node != parent[node])
        {
            parent[node] = find(parent[node]);
        }
        return parent[node];
    }

    void unionByRank(int u, int v)
    {
        int rootU = find(u);
        int rootV = find(v);

        if (rootU != rootV)
        {
            if (rank[rootU] < rank[rootV])
            {
                parent[rootU] = rootV;
            }
            else if (rank[rootU] > rank[rootV])
            {
                parent[rootV] = rootU;
            }
            else
            {
                parent[rootU] = rootV;
                rank[rootV]++;
            }
        }
    }
    void unionBySize(int u, int v)
    {
        int rootU = find(u);
        int rootV = find(v);

        if (rootU != rootV)
        {
            if (size[rootU] < size[rootV])
            {
                parent[rootU] = rootV;
                size[rootV] += size[rootU];
            }
            else
            {
                parent[rootV] = rootU;
                size[rootU] += size[rootV];
            }
        }
    }
    int maxi()
    {
        int k = *max_element(all(size));
        return k;
    }
};
int mul(int a, int b, int mod_value)
{
    return (a * 1LL * b) % mod_value;
}
int gcd(int a, int b)
{
    while (b != 0)
    {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}
int lcmx(int a, int b)
{
    return (a / gcd(a, b)) * b;
}
long long modExp(long long base, long long exp, long long mod)
{
    long long result = 1;
    while (exp > 0)
    {
        if (exp % 2 == 1)
        {
            result = (result * base) % mod;
        }
        base = (base * base) % mod;
        exp /= 2;
    }
    return result;
}
struct cmp
{
    bool operator()(const pair<int, int> &a, const pair<int, int> &b)
    {
        return a.first * b.second > a.second * b.first;
    }
};
bool isPerfectSquare(int n)
{
    int root = sqrt(n);
    return root * root == n;
}
int modularDivision(int x, int a, int m)
{
    int a_inv = modExp(a, m - 2, m);
    return (x * a_inv) % m;
}
struct cmpx
{
    bool operator()(const pair<int, int> &a, const pair<int, int> &b) const
    {
        if (a.first == b.first)
        {
            return a.second > b.second;
        }
        return a.first > b.first;
    }
};
bool cmpx1(const pair<int, int> &a, const pair<int, int> &b)
{
    if (a.first == b.first)
    {
        return a.second > b.second;
    }
    return a.first > b.first;
}
int ans(string a,string b,string c,int s1,int s2,int s3,vector<vector<int>>&dp){
    if(s1==si(a)){
        int ans=0;
        f(j,s3,len(c)-1){
            if(b[s2]!=c[j]){
                ans++;
            }
            s2++;
        }
        return ans;
    }
    if(s2==si(b)){
        int ans=0;
        f(j,s3,len(c)-1){
            if(a[s1]!=c[j]){
                ans++;
            }
            s1++;
        }
        return ans;
    }
    if(dp[s1][s2]!=-1){
        return dp[s1][s2];
    }
    int movefroma=ans(a,b,c,s1+1,s2,s3+1,dp);
    if(a[s1]!=c[s3]){
        movefroma++;
    }
    int movefromb=ans(a,b,c,s1,s2+1,s3+1,dp);
    if(b[s2]!=c[s3]){
        movefromb++;
    }
    return dp[s1][s2]=min(movefroma,movefromb);
}
void solve()
{
   string a,b,c;ci(a);ci(b);ci(c);
   vector<vector<int>>dp(si(a)+1,vector<int>(si(b)+1,-1));
   co(ans(a,b,c,0,0,0,dp));
}
int32_t main()
{
    int t;
    t = 1;
    cin >> t;
    f(i, 1, t)
    {
        solve();
        en;
    }
    // #ifndef ONLINE_JUDGE
    // cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
    // #endif
}

Answer: 1


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e5+5
vector<vector<int>> dp;
int solve(string a,string b,string c,int ind1,int ind2){
    // base case
    // cout<<ind1<<" "<<ind2<<endl;
    if(ind1 == a.size() && ind2 == b.size()){
        return 0;
    }
    if(dp[ind1][ind2] != -1){
        return dp[ind1][ind2];
    }
    int op1 = inf;
    int op2 = inf;
    int op3 = inf;
    int op4 = inf;

    if(a[ind1] == c[ind1+ind2] && ind1<a.size()){
        op1 = solve(a,b,c,ind1+1,ind2);
    }
    if(b[ind2] == c[ind1+ind2] && ind2<b.size()){
        op2 = solve(a,b,c,ind1,ind2+1);
    }
    if(ind1<a.size())op3 = 1 + solve(a,b,c,ind1+1,ind2);
    if(ind2<b.size())op4 = 1 + solve(a,b,c,ind1,ind2+1);
    return min({op1,op2,op3,op4});
}

signed main(){
    int t;
    cin>>t;
    while(t--){
        string a,b,c;
        cin>>a>>b>>c;
        int n = a.size();
        int m = b.size();
        int k = c.size();
        dp = vector<vector<int>>(n+1,vector<int>(m+1,-1));
        dp[n][m] = 0;
        int ans = solve(a,b,c,0,0);
        cout<<ans<<endl;
    }
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e5+5
vector<vector<int>> dp;
int solve(string a,string b,string c,int ind1,int ind2){
    // base case
    // cout<<ind1<<" "<<ind2<<endl;
    if(ind1 == a.size() && ind2 == b.size()){
        return 0;
    }
    if(dp[ind1][ind2] != -1){
        return dp[ind1][ind2];
    }
    int op1 = inf;
    int op2 = inf;
    int op3 = inf;
    int op4 = inf;

    if(a[ind1] == c[ind1+ind2] && ind1<a.size()){
        op1 = solve(a,b,c,ind1+1,ind2);
    }
    if(b[ind2] == c[ind1+ind2] && ind2<b.size()){
        op2 = solve(a,b,c,ind1,ind2+1);
    }
    if(ind1<a.size())op3 = 1 + solve(a,b,c,ind1+1,ind2);
    if(ind2<b.size())op4 = 1 + solve(a,b,c,ind1,ind2+1);
    return dp[ind1][ind2] = min({op1,op2,op3,op4});
}

signed main(){
    int t;
    cin>>t;
    while(t--){
        string a,b,c;
        cin>>a>>b>>c;
        int n = a.size();
        int m = b.size();
        int k = c.size();
        dp = vector<vector<int>>(n+1,vector<int>(m+1,-1));
        dp[n][m] = 0;
        // int ans = solve(a,b,c,0,0);
        for(int i=(n);i>=0;i--){
            for(int j=(m);j>=0;j--){
                if(i==n && j==m) continue;
                int op1 = inf;
                int op2 = inf;
                int op3 = inf;
                int op4 = inf;
                if(i<n && a[i] == c[i+j]){
                    op1 = dp[i+1][j];
                }
                if(j<m && b[j] == c[i+j]){
                    op2 = dp[i][j+1];
                }
                if(i<n)op3 = 1 + dp[i+1][j];
                if(j<m)op4 = 1 + dp[i][j+1];
                dp[i][j] = min(op1,min(op2,min(op3,op4)));
            }
        }
        cout<<dp[0][0]<<endl;
        // cout<<ans<<endl;
    }
}

Answer: 2


//package codeforcesques;
import java.util.*;
import java.io.*;
public class ThreeStrings {
    int mincount = Integer.MAX_VALUE;

    public static void main(String[] args) {
        FastReader fs = new FastReader();

        int t = fs.nextInt();

        while (t-- > 0) {
            String s1 = fs.nextLine();
            String s2 = fs.nextLine();
            String s3 = fs.nextLine();
            ThreeStrings d = new ThreeStrings();
            int[][] dp = new int[s1.length()][s2.length()];
            for (int i = 0; i < s1.length(); i++) {
                Arrays.fill(dp[i], -1);
            }
            System.out.println( s3.length()-rec(0, 0, 0, s1, s2, s3, dp));
        }
    }
    public static int rec(int n, int i, int j, String a, String b, String c, int[][] dp) {
        if (i == a.length()) {
            int val = 0;
            while (j < b.length()) {
                if (b.charAt(j) == c.charAt(n)) {
                    val++;
                }
                j++;
                n++;
            }
            return val;
        }
        if (j == b.length()) {
            int val = 0;
            while (i < a.length()) {
                if (a.charAt(i) == c.charAt(n)) {
                    val++;
                }
                i++;
                n++;
            }
            return val;
        }
        if (dp[i][j] != -1) {
            return dp[i][j];
        }
        int c1 = 0;
        int c2 = 0;
        if (a.charAt(i) == c.charAt(n)) {
            c1++;
        }
        if (b.charAt(j) == c.charAt(n)) {
            c2++;
        }
        int max1 = rec(n + 1, i + 1, j, a, b, c, dp) + c1;
        int max2 = rec(n + 1, i, j + 1, a, b, c, dp) + c2;
        dp[i][j] = Math.max(max1, max2);
        return dp[i][j];
    }
}
class FastReader {
    BufferedReader gt;
    StringTokenizer st;

    public FastReader() {
        gt = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(gt.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    String nextLine() {
        String str = "";
        try {
            str = gt.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    int[] readIntArray(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n; i++)
            res[i] = nextInt();
        return res;
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    long[] readLongArray(int n) {
        long[] res = new long[n];
        for (int i = 0; i < n; i++)
            res[i] = nextLong();
        return res;
    }

    String[] readStringArray(int n) {
        String[] str = new String[n];
        for (int i = 0; i < n; i++)
            str[i] = nextLine();

        return str;
    }

    int getGCD(int a, int b) {
        if (b == 0)
            return a;
        else
            return getGCD(b, a % b);
    }
}

//package codeforcesques;
import codeforcesques.AbsoluteSorting;

import java.util.*;
import java.io.*;
public class ThreeStrings {
    int mincount=Integer.MAX_VALUE;
    public static void main(String[] args) {
        FastReader fs=new FastReader();

        int t=fs.nextInt();

        while(t-->0)
        {
            String s1=fs.nextLine();
            String s2=fs.nextLine();
            String s3=fs.nextLine();
            ThreeStrings d=new ThreeStrings();
            int [][]dp=new int[s1.length()][s2.length()];
            for(int i=0;i<s1.length();i++)
            {
                Arrays.fill(dp[i],-1);
            }
           d.rec(0,0,0,s1,s2,s3,dp);
           System.out.println(d.mincount);

        }
    }
    public static int rec(int n, int i, int j, String a, String b, String c, int[][] dp){
        if(i==a.length()){
            int val = 0;
            while(j<b.length()){
                if(b.charAt(j)==c.charAt(n)){
                    val++;
                }
                j++;
                n++;
            }
            return val;
        }
        if(j==b.length()){
            int val = 0;
            while(i<a.length()){
                if(a.charAt(i)==c.charAt(n)){
                    val++;
                }
                i++;
                n++;
            }
            return val;
        }
        if(dp[i][j]!=-1){
            return dp[i][j];
        }
        int c1 = 0;
        int c2 = 0;
        if(a.charAt(i)==c.charAt(n)){
            c1++;
        }
        if(b.charAt(j)==c.charAt(n)){
            c2++;
        }
        int max1 = rec(n+1,i+1,j,a,b,c,dp)+c1;
        int max2 = rec(n+1,i,j+1,a,b,c,dp)+c2;
        dp[i][j] = Math.max(max1, max2);
        return dp[i][j];
    }
class FastReader {
    BufferedReader gt;
    StringTokenizer st;

    public FastReader() {
        gt = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(gt.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    String nextLine() {
        String str = "";
        try {
            str = gt.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    int[] readIntArray(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n; i++)
            res[i] = nextInt();
        return res;
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    long[] readLongArray(int n) {
        long[] res = new long[n];
        for (int i = 0; i < n; i++)
            res[i] = nextLong();
        return res;
    }

    String[] readStringArray(int n) {
        String[] str = new String[n];
        for (int i = 0; i < n; i++)
            str[i] = nextLine();

        return str;
    }
    int getGCD(int a,int b)
    {
        if(b==0)
            return a;
        else
            return getGCD(b,a%b);
    }
}

Answer: 1


Answer: 2


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define vi vector <int>

#define vll vector <ll>

#define vp vector<pair<ll,ll>>

#define all(a) (a).begin(),(a).end()

#define rep(i,a) for(int i=0;i<a;i++)

#define fa(v) for (auto &it : (v))

#define ff first

#define ss second

#define pb push_back

#define pl pair<ll ,ll>

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

int t; cin>>t;

while (t--){

    string a,b,c; cin>>a>>b>>c;

    int n =a.size(), m = b.size() ;

    vector<vector<int>> dp(n+1, vector<int>(m+1,0)) ;

    dp[n][m]=0;

    for(int i=n-1;i>=0;i--){

        if(a[i]==c[m+i])dp[i][m]=dp[i+1][m];

        else {

            dp[i][m]=dp[i+1][m]+1;

        }

    }

    for(int i=m-1;i>=0;i--){

        if(b[i]==c[n+i])dp[n][i]=dp[n][i+1];

        else{

            dp[n][i]= dp[n][i+1]+1;

        }

    }

    for(int i=n-1;i>=0;i--){

        for(int j=m-1;j>=0;j--){

            int x= 1e5,y = 1e5;

            if(a[i]==c[i+j])x=dp[i+1][j];

            else{x= dp[i+1][j]+1 ;}

            if(b[j]==c[i+j])y=dp[i][j+1];

            else {y= dp[i][j+1]+1;}

            dp[i][j] = min(x,y) ;

        }

    }

    cout<< dp[0][0] <<endl ;

}

}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define vi vector <int>

#define vll vector <ll>

#define vp vector<pair<ll,ll>>

#define all(a) (a).begin(),(a).end()

#define rep(i,a) for(int i=0;i<a;i++)

#define fa(v) for (auto &it : (v))

#define ff first

#define ss second

#define pb push_back

#define pl pair<ll ,ll>

    int rec(  vector<vector<int>> &dp,  string a,string b , string c, int i, int j){

        if(i+j>=c.size())return 0 ;

        // dp[i][j] == minimun changes req after index i , j ...

        if( dp[i][j]!=-1)return dp[i][j] ;

            int x = 1e7, y = 1e7, z= 1e7, w = 1e7 ;

            if(i<a.size()){

                x=rec(dp,a,b,c,i+1,j)+1;

                if(c[i+j]==a[i]) z= rec(dp,a,b,c,i+1,j) ;

                z=min(x,z);

            }

            if(j<b.size()){y=rec(dp,a,b,c,i,j+1)+1;

                if(c[i+j]==b[j])w = rec( dp, a,b,c ,i, j+1) ;

                w= min(y,w);

            }

//cout<<x<<z<<y<<x<<endl;

            return dp[i][j]= min(z,w) ;

        return 0 ;

    }

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

int t; cin>>t;

while (t--){

    string a,b,c; cin>>a>>b>>c;

    int n =a.size(), m = b.size() ;

    vector<vector<int>> dp(n+1, vector<int>(m+1,-1)) ;

    cout<<rec(dp, a,b,c,0,0)<<endl ;

}

}

Answer: 1


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// # define int long long
#define f(x, a, b) for (ll x = a; x < b; x++)
#define fm(x, a, b) for (int x = a; x > b; x--)
#define ll long long
#define pb push_back

long long gcd(long long a, ll b)
{
  return b == 0 ? a : gcd(b, a % b);
}

long long lcm(ll a, ll b)
{
  return (a / gcd(a, b)) * b;
}

int help(vector<vector<int>>& dp,string& a,string& b,string& c,int i,int j,int n,int m, int o){
    if (i==n){
        int ans=0;
        f(k,j,m){
            if (c[n+k]!=b[k]){ans+=1;}
        }
        return ans;
    }
    if (j==m){
        int ans=0;
        f(k,i,n){
            if (c[m+k]!=a[k]){ans+=1;}
        }
        return ans;
    }
    if (dp[i][j]!=-1){return dp[i][j];}
    if (a[i]==c[i+j]){
        if (b[j]==c[i+j]){
            // int x=help(dp,a,b,c,i+1,j,n,m,o);
            // int y=help(dp,a,b,c,i,j+1,n,m,o);
            dp[i][j]=help(dp,a,b,c,i,j+1,n,m,o);;
        }
        else{
            int x=help(dp,a,b,c,i+1,j,n,m,o);
            int y=help(dp,a,b,c,i,j+1,n,m,o)+1;
            dp[i][j]=min(x,y);
        }
    }
    else if (b[j]==c[i+j]){
            int x=help(dp,a,b,c,i+1,j,n,m,o)+1;
            int y=help(dp,a,b,c,i,j+1,n,m,o);
            dp[i][j]=min(x,y);
    }
    else{
        int x=help(dp,a,b,c,i+1,j,n,m,o)+1;
        int y=help(dp,a,b,c,i,j+1,n,m,o)+1;
        dp[i][j]=min(x,y);
    }
    return dp[i][j];
}

int main()
{
  int t;
  t = 1;
  cin >> t;
  while (t--)
  {
   	string a,b,c; cin>>a>>b>>c;
   	int n=a.size(),m=b.size(),o=c.size();
   	vector<vector<int>> dp(n,vector<int>(m,-1));
   	int ans=help(dp,a,b,c,0,0,n,m,o);
   	cout<<ans<<endl;
  }
  return 0;
}

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// # define int long long
#define f(x, a, b) for (ll x = a; x < b; x++)
#define fm(x, a, b) for (int x = a; x > b; x--)
#define ll long long
#define pb push_back

long long gcd(long long a, ll b)
{
  return b == 0 ? a : gcd(b, a % b);
}

long long lcm(ll a, ll b)
{
  return (a / gcd(a, b)) * b;
}

int help(vector<vector<int>>& dp,string& a,string& b,string& c,int i,int j,int n,int m, int o){
    if (i==n){
        int ans=0;
        f(k,j,m){
            if (c[n+k]!=b[k]){ans+=1;}
        }
        return ans;
    }
    if (j==m){
        int ans=0;
        f(k,i,n){
            if (c[m+k]!=a[k]){ans+=1;}
        }
        return ans;
    }
    if (dp[i][j]!=-1){return dp[i][j];}
    if (a[i]==c[i+j]){
        if (b[j]==c[i+j]){
            int x=help(dp,a,b,c,i+1,j,n,m,o);
            int y=help(dp,a,b,c,i,j+1,n,m,o);
            dp[i][j]=min(x,y);
        }
        else{
            int x=help(dp,a,b,c,i+1,j,n,m,o);
            int y=help(dp,a,b,c,i,j+1,n,m,o)+1;
            dp[i][j]=min(x,y);
        }
    }
    else if (b[j]==c[i+j]){
            int x=help(dp,a,b,c,i+1,j,n,m,o)+1;
            int y=help(dp,a,b,c,i,j+1,n,m,o);
            dp[i][j]=min(x,y);
    }
    else{
        int x=help(dp,a,b,c,i+1,j,n,m,o)+1;
        int y=help(dp,a,b,c,i,j+1,n,m,o)+1;
        dp[i][j]=min(x,y);
    }
    return dp[i][j];
}

int main()
{
  int t;
  t = 1;
  cin >> t;
  while (t--)
  {
   	string a,b,c; cin>>a>>b>>c;
   	int n=a.size(),m=b.size(),o=c.size();
   	vector<vector<int>> dp(n,vector<int>(m,-1));
   	int ans=help(dp,a,b,c,0,0,n,m,o);
   	cout<<ans<<endl;
  }
  return 0;
}

Answer: 2


import sys, random, math, string, itertools
from copy import deepcopy
from collections import defaultdict, Counter, deque
from heapq import heapify, heappush, heappop
from functools import cache
from bisect import bisect_left, bisect_right
from types import GeneratorType
from typing import *

input = lambda: sys.stdin.readline().strip()

def debug(*x, **y):
    if not DEBUG_ENABLED:
        return
    print(*x, (y if y != {} else "\b"), file=sys.stderr)

###############################################################################

sys.setrecursionlimit(2*(10**3)+50)

def solve_bruteforce(case=None):
    pass

def execute_once():
    pass

def solve(case=None):
    a,b,c = input(),input(),input()

    @cache
    def dp(i,j):
        ind = i+j

        if ind == len(c):
            return 0

        ch = c[ind]

        return min(
            (dp(i+1,j) + (1 if a[i] != ch else 0) ) if i < len(a) else math.inf,
            (dp(i,j+1) + (1 if b[j] != ch else 0) ) if j < len(b) else math.inf
        )

    ans = dp(0,0)
    print(ans)

INPUT_NUMBER_OF_TEST_CASES = 1
SKIP_SOLVE = 0
DEBUG_ENABLED = 1
MOD = 10**9 + 7
BOOLEAN_RETURN = 0
TRUE_MAPPING, FALSE_MAPPING = "YES", "NO"

###############################################################################

class CustomHashMap:
    def __init__(self, map_type=dict, arg=None):
        """
        Custom HashMap for Python's Anti-hash-table test
        :param map_type: type of the map (allowed types: dict, defaultdict, Counter)
        :param arg: argument for the map (should be list if map_type is Counter and function if map_type is defaultdict)
        """
        self.RANDOM = random.randrange(2**62)
        if map_type == Counter:
            self.dict = map_type([self.wrapper(i) for i in arg])
        elif map_type == defaultdict:
            self.dict = map_type(arg)
        else:
            self.dict = map_type()

    def wrapper(self, num):
        return num ^ self.RANDOM

    def __setitem__(self, key, value):
        self.dict[self.wrapper(key)] = value

    def __getitem__(self, key):
        return self.dict[self.wrapper(key)]

    def __contains__(self, key):
        return self.wrapper(key) in self.dict

    def __iter__(self):
        return iter(self.wrapper(i) for i in self.dict)

    def keys(self):
        return [self.wrapper(i) for i in self.dict]

    def values(self):
        return [i for i in self.dict.values()]

    def items(self):
        return [(self.wrapper(i), j) for i, j in self.dict.items()]

    def __repr__(self):
        return repr({self.wrapper(i): j for i, j in self.dict.items()})

def recursion_limit_fix(f):
    """
    recursion limit fix decorator, change 'return' to 'yield' and add 'yield' before calling the function
    and add 'yield' after the function if not returning anything
    """
    stack = []

    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

def binary_search(left, right, check, start_from_left):
    if start_from_left:
        ans = left
    else:
        ans = right
    while left <= right:
        mid = (left + right) // 2
        if start_from_left:
            if check(mid):
                ans, left = mid, mid + 1
            else:
                right = mid - 1
        else:
            if check(mid):
                ans, right = mid, mid - 1
            else:
                left = mid + 1
    return ans

execute_once()

if not SKIP_SOLVE:
    for t in range(int(input()) if INPUT_NUMBER_OF_TEST_CASES else 1):
        if BOOLEAN_RETURN:
            print(TRUE_MAPPING if solve(t + 1) else FALSE_MAPPING)
        else:
            solve(t + 1)

import sys, random, math, string, itertools
from copy import deepcopy
from collections import defaultdict, Counter, deque
from heapq import heapify, heappush, heappop
from functools import cache
from bisect import bisect_left, bisect_right
from types import GeneratorType
from typing import *

input = lambda: sys.stdin.readline().strip()

def debug(*x, **y):
    if not DEBUG_ENABLED:
        return
    print(*x, (y if y != {} else "\b"), file=sys.stderr)

###############################################################################

def solve_bruteforce(case=None):
    pass

def execute_once():
    pass

def solve(case=None):
    a,b,c = input(),input(),input()

    # @cache
    # def dp(i,j):
    #     ind = i+j

    #     if ind == len(c):
    #         return 0

    #     ch = c[ind]

    #     return min(
    #         (dp(i+1,j) + (1 if a[i] != ch else 0) ) if i < len(a) else math.inf,
    #         (dp(i,j+1) + (1 if b[j] != ch else 0) ) if j < len(b) else math.inf
    #     )

    n,m = len(a),len(b)

    dp = [[math.inf]*(m+1) for _ in range(n+1)]
    dp[-1][-1] = 0

    for i in range(n,-1,-1):
        for j in range(m,-1,-1):
            if i+j == len(c):
                continue

            ch = c[i+j]

            if i < n:
                dp[i][j] = min(dp[i][j], dp[i+1][j] + (1 if a[i] != ch else 0))
            if j < m:
                dp[i][j] = min(dp[i][j], dp[i][j+1] + (1 if b[j] != ch else 0))

    # for i in dp:
    #     print(i)

    ans = dp[0][0]
    print(ans)

INPUT_NUMBER_OF_TEST_CASES = 1
SKIP_SOLVE = 0
DEBUG_ENABLED = 1
MOD = 10**9 + 7
BOOLEAN_RETURN = 0
TRUE_MAPPING, FALSE_MAPPING = "YES", "NO"

###############################################################################

class CustomHashMap:
    def __init__(self, map_type=dict, arg=None):
        """
        Custom HashMap for Python's Anti-hash-table test
        :param map_type: type of the map (allowed types: dict, defaultdict, Counter)
        :param arg: argument for the map (should be list if map_type is Counter and function if map_type is defaultdict)
        """
        self.RANDOM = random.randrange(2**62)
        if map_type == Counter:
            self.dict = map_type([self.wrapper(i) for i in arg])
        elif map_type == defaultdict:
            self.dict = map_type(arg)
        else:
            self.dict = map_type()

    def wrapper(self, num):
        return num ^ self.RANDOM

    def __setitem__(self, key, value):
        self.dict[self.wrapper(key)] = value

    def __getitem__(self, key):
        return self.dict[self.wrapper(key)]

    def __contains__(self, key):
        return self.wrapper(key) in self.dict

    def __iter__(self):
        return iter(self.wrapper(i) for i in self.dict)

    def keys(self):
        return [self.wrapper(i) for i in self.dict]

    def values(self):
        return [i for i in self.dict.values()]

    def items(self):
        return [(self.wrapper(i), j) for i, j in self.dict.items()]

    def __repr__(self):
        return repr({self.wrapper(i): j for i, j in self.dict.items()})

def recursion_limit_fix(f):
    """
    recursion limit fix decorator, change 'return' to 'yield' and add 'yield' before calling the function
    and add 'yield' after the function if not returning anything
    """
    stack = []

    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to

    return wrappedfunc

def binary_search(left, right, check, start_from_left):
    if start_from_left:
        ans = left
    else:
        ans = right
    while left <= right:
        mid = (left + right) // 2
        if start_from_left:
            if check(mid):
                ans, left = mid, mid + 1
            else:
                right = mid - 1
        else:
            if check(mid):
                ans, right = mid, mid - 1
            else:
                left = mid + 1
    return ans

execute_once()

if not SKIP_SOLVE:
    for t in range(int(input()) if INPUT_NUMBER_OF_TEST_CASES else 1):
        if BOOLEAN_RETURN:
            print(TRUE_MAPPING if solve(t + 1) else FALSE_MAPPING)
        else:
            solve(t + 1)

Answer: 2


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

const int N = 1e3 + 2;
int dp[N][N] = { { 0 } };

string a, b, c;

int n; // length of a
int m; // length of b

int f(int i, int j) {
  if (i == 0 && j == 0) return 0;
  if (dp[i][j] != 0) return dp[i][j];
  int choose_a = INT_MAX, choose_b = INT_MAX;
  if (i > 0) choose_a = (a[i - 1] == c[i + j - 1] ? 0 : 1) + f(i - 1, j);
  if (j > 0) choose_b = (b[j - 1] == c[i + j - 1] ? 0 : 1) + f(i, j - 1);
  return dp[i][j] = min(choose_a, choose_b);
}

void solve() {
  cin >> a >> b >> c;
  n = a.length();
  m = b.length();
  memset(dp, 0, sizeof(dp));
  cout << f(n, m) << endl;
}

int main() {
  int t;
  cin >> t;
  while (t--) solve();
}

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

const int N = 1e3 + 2;
int dp[N][N] = { { 0 } };

string a, b, c;

int n; // length of a
int m; // length of b

int f(int i, int j) {
  if (i == 0 && j == 0) return 0;
  if (dp[i][j] != 0) return dp[i][j];
  int choose_a = INT_MAX, choose_b = INT_MAX;
  if (i > 0) choose_a = (a[i - 1] == c[i + j - 1] ? 0 : 1) + f(i - 1, j);
  if (j > 0) choose_b = (b[j - 1] == c[i + j - 1] ? 0 : 1) + f(i, j - 1);
  return dp[i][j] = min(choose_a, choose_b);
}

void solve() {
  cin >> a >> b >> c;
  n = a.length();
  m = b.length();
  cout << f(n, m) << endl;
}

int main() {
  int t;
  cin >> t;
  while (t--) solve();
}

Answer: 1


Answer: 1


#include<bits/stdc++.h>
using namespace std;
#define cin(a) for(auto i =0;i<=a.size()-1;i++) cin>>a[i];
#define all(a) a.begin(),a.end()
#define ll long long
#define yy cout<<"Yes"<<endl
#define nn cout<<"No"<<endl
// const int N=3e5+2;
// int tree[4*N];
// void build(vector<int> &a,int nd,int s,int e){
//   if(s==e){
//   tree[nd]=a[s];
//   return;
//   }
//  int mid=(s+e)/2;
//  build(a,2*nd,s,mid);
//  build(a,2*nd+1,mid+1,e);
//   tree[nd]=__gcd(tree[2*nd],tree[2*nd+1]);
// }
// int qur(int nd,int s,int e,int l,int r){
//   //non-overlap interval
//   if(l>r){
//     return 0;
//   }
//   if(s>r||e<l){
//     return -1;
//   }
//   if(l<=s&&e<=r){
//     return tree[nd];
//   }
//     int mid=(s+e)/2;
//  int q1=qur(2*nd,s,mid,l,r);
//  int q2=qur(2*nd+1,mid+1,e,l,r);
// return __gcd(q1,q2);
// }
void solve(){
string a,b,c;
cin>>a;
cin>>b;
cin>>c;
vector<vector<ll>> dp(a.size()+1,vector<ll> (b.size()+1,LONG_LONG_MAX));
dp[0][0]=0;
for(int i=1;i<=c.size();i++){
  for(int j=0;j<=i;j++){
    if(j>a.size()||i-j>b.size()){
      continue;
    }
    if(j>0){
    dp[j][i-j]=min(dp[j][i-j],dp[j-1][i-j]+(c[i-1]!=a[j-1]));
    }
    if(i-j>0){
      dp[j][i-j]=min(dp[j][i-j],dp[j][i-j-1]+(c[i-1]!=b[i-j-1]));
    }
}}
cout<<dp[a.size()][b.size()]<<endl;
}
int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
int t;
cin>>t;
while(t--){
    solve();
}}

#include<bits/stdc++.h>
using namespace std;
#define cin(a) for(auto i =0;i<=a.size()-1;i++) cin>>a[i];
#define all(a) a.begin(),a.end()
#define ll long long
#define yy cout<<"Yes"<<endl
#define nn cout<<"No"<<endl
// const int N=3e5+2;
// int tree[4*N];
// void build(vector<int> &a,int nd,int s,int e){
// if(s==e){
// tree[nd]=a[s];
// return;
// }
// int mid=(s+e)/2;
// build(a,2*nd,s,mid);
// build(a,2*nd+1,mid+1,e);
// tree[nd]=__gcd(tree[2*nd],tree[2*nd+1]);
// }
// int qur(int nd,int s,int e,int l,int r){
// //non-overlap interval
// if(l>r){
// return 0;
// }
// if(s>r||e<l){
// return -1;
// }
// if(l<=s&&e<=r){
// return tree[nd];
// }
// int mid=(s+e)/2;
// int q1=qur(2*nd,s,mid,l,r);
// int q2=qur(2*nd+1,mid+1,e,l,r);
// return __gcd(q1,q2);
// }
void solve(){
string a,b,c;
cin>>a;
cin>>b;
cin>>c;
vector<vector<ll>> dp(a.size()+1,vector<ll> (b.size()+1,LONG_LONG_MAX));
dp[0][0]=0;
for(int i=1;i<=c.size();i++){
 for(int j=0;j<=i;j++){
 if(j>a.size()||i-j>b.size()){
 continue;
 }
 if(j>0){
 dp[j][i-j]=min(dp[j][i-j],dp[j-1][i-j]+(c[i-1]!=a[j-1]));
 }
 if(i-j>0){
 dp[j][i-j]=min(dp[j][i-j],dp[j][i-j-1]+(c[i-1]!=b[i-j-1]));
 }
}}
cout<<dp[a.size()][b.size()]<<endl;
}
int main(){
 ios_base::sync_with_stdio(false);
 cin.tie(0);
 cout.tie(0);
int t;
cin>>t
while(t--){
 solve();
}}

Answer: 1


#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

#define x first
#define y second

const int N = 2e3 + 10;

int qmi(int a, int k, int p)  // 求a^k mod p
{
    int res = 1 % p;
    while (k)
    {
        if (k & 1) res = (LL)res * a % p;
        a = (LL)a * a % p;
        k >>= 1;
    }
    return res;
}

int n, k;
char s1[N], s2[N], t[N];
int f[N][N];

void solve()
{
    cin >> s1 + 1 >> s2 + 1 >> t + 1;
    int l1 = strlen(s1 + 1), l2 = strlen(s2 + 1);
    // memset(f, 0x3f, sizeof f);
    // for(int i = 0; i <= l1; i ++) f[i][0] = 0;
    // for(int j = 0; j <= l2; j ++) f[0][j] = 0;

    for(int i = 0; i <= l1; i ++)
        for(int j = 0; j <= l2; j ++)
        {
            if(i == 0 && j == 0) continue;
            if(i != 0)
                f[i][j] = f[i - 1][j] + (s1[i] == t[i + j]);
            if(j != 0)
                f[i][j] = max(f[i][j], f[i][j - 1] + (s2[j] == t[i + j]));
        }
    cout << l1 + l2 - f[l1][l2] << endl;
}

int main()
{
    int t;
    cin >> t;
    while(t --)
        solve();
}

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

#define x first
#define y second

const int N = 2e3 + 10;

int qmi(int a, int k, int p)  // 求a^k mod p
{
    int res = 1 % p;
    while (k)
    {
        if (k & 1) res = (LL)res * a % p;
        a = (LL)a * a % p;
        k >>= 1;
    }
    return res;
}

int n, k;
char s1[N], s2[N], t[N];
int f[N][N];

void solve()
{
    cin >> s1 + 1 >> s2 + 1 >> t + 1;
    int l1 = strlen(s1 + 1), l2 = strlen(s2 + 1);
    // memset(f, 0x3f, sizeof f);
    // for(int i = 0; i <= l1; i ++) f[i][0] = 0;
    // for(int j = 0; j <= l2; j ++) f[0][j] = 0;

    for(int i = 0; i <= l1; i ++)
        for(int j = 0; j <= l2; j ++)
        {
            f[i][j] = 0;
            if(i == 0 && j == 0) continue;
            if(i != 0)
                f[i][j] = f[i - 1][j] + (s1[i] == t[i + j]);
            if(j != 0)
                f[i][j] = max(f[i][j], f[i][j - 1] + (s2[j] == t[i + j]));
        }
    cout << l1 + l2 - f[l1][l2] << endl;
}

int main()
{
    int t;
    cin >> t;
    while(t --)
        solve();
}

Answer: 2


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

int func(string& a, string& b, string& c, int i1, int i2, int j, vector<vector<vector<int>>>& dp) {
    if (j == c.size()) return 0;

    if (dp[i1][i2][j] != -1) return dp[i1][i2][j];

    int mini = INT_MAX;

    if (i1 < a.size()) {
        mini = min(mini, (a[i1] != c[j]) + func(a, b, c, i1+1, i2, j+1, dp));
    }

    if (i2 < b.size()) {
        mini = min(mini, (b[i2] != c[j]) + func(a, b, c, i1, i2+1, j+1, dp));
    }

    return dp[i1][i2][j] = mini;
}

void solve() {
    string a, b, c;
    cin >> a >> b >> c;

    int n1 = a.size(), n2 = b.size(), n3 = c.size();
    vector<vector<vector<int>>> dp(n1+1, vector<vector<int>>(n2+1, vector<int>(n3+1, -1)));

    int ans = func(a, b, c, 0, 0, 0, dp);
    cout << ans << endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

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

int func(string& a, string& b, string& c, int i1, int i2, int j, vector<vector<int>>& dp) {
    if (j == c.size()) return 0;

    if (dp[i1][i2] != -1) return dp[i1][i2];

    int mini = INT_MAX;

    if (i1 < a.size()) {
        mini = min(mini, (a[i1] != c[j]) + func(a, b, c, i1+1, i2, j+1, dp));
    }

    if (i2 < b.size()) {
        mini = min(mini, (b[i2] != c[j]) + func(a, b, c, i1, i2+1, j+1, dp));
    }

    return dp[i1][i2] = mini;
}

void solve() {
    string a, b, c;
    cin >> a >> b >> c;

    int n1 = a.size(), n2 = b.size(), n3 = c.size();
    vector<vector<int>> dp(n1+1, vector<int>(n2+1,-1));

    int ans = func(a, b, c, 0, 0, 0, dp);
    cout << ans << endl;
}

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

Answer: 2


#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<climits>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<queue>
#define ll long long int
using namespace std;

int solve(string a,string b,string c,int i,int j,int s,vector<vector<vector<int> > >&dp){
    if(i==a.size() && j==b.size()){
        if(s==1){
            if(a[i-1]!=c[i+j+1-2]){
                return dp[i][j][s]=1;
            }
            return  dp[i][j][s]=0;
        }
        if(b[j-1]!=c[i+j+1-2]){
            return  dp[i][j][s]=1;
        }
        return  dp[i][j][s]=0;

    }
    if(dp[i][j][s]!=-1){
        return dp[i][j][s];
    }
    if(s==1){
        int cmp=i+j+1-2;
        int add=0;
        if(a[i-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+solve(a,b,c,i+1,j,1,dp);
        }

        if(j+1<=b.size()-1+1){
            c2=add+solve(a,b,c,i,j+1,0,dp);
        }

        return  dp[i][j][s]=min(c1,c2);

        }
        int cmp=i+j+1-2;
        int add=0;
        if(b[j-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+solve(a,b,c,i+1,j,1,dp);
        }

        if(j+1<=b.size()-1+1){
            c2=add+solve(a,b,c,i,j+1,0,dp);
        }

        return  dp[i][j][s]=min(c1,c2);

}
int solve2(string a,string b,string c){
    int n1=a.size();
    int n2=b.size();

    vector<vector<vector<int> > >dp(n1+1,vector<vector<int> >(n2+1,vector<int>(2,0)));

    for(int i=a.size();i>=0;i--){
        for(int j=b.size();j>=0;j--){
            for(int s=0;s<=1;s++){
                if(i==a.size() && j==b.size()){
        if(s==1){
            if(a[i-1]!=c[i+j+1-2]){
                 dp[i][j][s]=1;
            }
              dp[i][j][s]=0;
        }
        else if(b[j-1]!=c[i+j+1-2]){
           dp[i][j][s]=1;
        }
        else{
         dp[i][j][s]=0;}
         continue;

    }

    if(s==1){
        int cmp=i+j+1-2;
        int add=0;
        if(a[i-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+dp[i+1][j][1];
        }

        if(j+1<=b.size()-1+1){
            c2=add+dp[i][j+1][0];
        }

         dp[i][j][s]=min(c1,c2);

        }

        else{
        int cmp=i+j+1-2;
        int add=0;
        if(b[j-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+dp[i+1][j][1];
        }

        if(j+1<=b.size()-1+1){
            c2=add+dp[i][j+1][0];
        }

         dp[i][j][s]=min(c1,c2);
        }

            }
        }
    }

    return dp[1][0][1];

}

int main(){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);
     int t=1;
     cin>>t;
     while(t--){
        string a;
        cin>>a;

        string b;
        cin>>b;

        string c;
        cin>>c;
        int n1=a.size();
        int n2=b.size();

       // vector<vector<vector<int> > >dp1(n1+1,vector<vector<int> >(n2+1,vector<int>(2,-1)));
        // vector<vector<vector<int> > >dp2(n1+1,vector<vector<int> >(n2+1,vector<int>(2,-1)));

        int ans1=solve2(a,b,c);
        //int ans2=solve(a,b,c,0,1,0,dp2);

        cout<<ans1<<endl;

     }

}

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<climits>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<queue>
#define ll long long int
using namespace std;

int solve(string &a,string &b,string &c,int i,int j,int s,vector<vector<vector<int> > >&dp){
    if(i==a.size() && j==b.size()){
        if(s==1){
            if(a[i-1]!=c[i+j+1-2]){
                return dp[i][j][s]=1;
            }
            return  dp[i][j][s]=0;
        }
        if(b[j-1]!=c[i+j+1-2]){
            return  dp[i][j][s]=1;
        }
        return  dp[i][j][s]=0;

    }
    if(dp[i][j][s]!=-1){
        return dp[i][j][s];
    }
    if(s==1){
        int cmp=i+j+1-2;
        int add=0;
        if(a[i-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+solve(a,b,c,i+1,j,1,dp);
        }

        if(j+1<=b.size()-1+1){
            c2=add+solve(a,b,c,i,j+1,0,dp);
        }

        return  dp[i][j][s]=min(c1,c2);

        }
        int cmp=i+j+1-2;
        int add=0;
        if(b[j-1]!=c[cmp]){
            add=1;
        }
        int c1=1e9,c2=1e9;
        if(i+1<=a.size()-1+1){
            c1=add+solve(a,b,c,i+1,j,1,dp);
        }

        if(j+1<=b.size()-1+1){
            c2=add+solve(a,b,c,i,j+1,0,dp);
        }

        return  dp[i][j][s]=min(c1,c2);

}

int main(){
    ios_base::sync_with_stdio(false);
     cin.tie(NULL);
     int t=1;
     cin>>t;
     while(t--){
        string a;
        cin>>a;

        string b;
        cin>>b;

        string c;
        cin>>c;
        int n1=a.size();
        int n2=b.size();

        vector<vector<vector<int> > >dp1(n1+1,vector<vector<int> >(n2+1,vector<int>(2,-1)));
         vector<vector<vector<int> > >dp2(n1+1,vector<vector<int> >(n2+1,vector<int>(2,-1)));

        int ans1=solve(a,b,c,1,0,1,dp1);
        int ans2=solve(a,b,c,0,1,0,dp2);

        cout<<min(ans1,ans2)<<endl;

     }

}

Answer: 2


#include <bits/stdc++.h>
using namespace std;
#define int long long
int power(int A, int expo)
{
    if (expo == 0)
        return 1;
    int res = power(A, expo / 2);
    if (expo % 2)
        return res * res * A;
    else
        return res * res;
}
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int fact(int x)
{
    if (x == 1 || x == 0)
        return 1;
    return (x * fact(x - 1));
}
class UnionFind{
    private: vector<int> parent,rank;
    public:
        UnionFind(int n){
            rank.assign(n,0);
            parent.assign(n,0);
            iota(parent.begin(),parent.end(),0);
        }
        int find(int x) {
            if(parent[x] == x)
                return x;

            return parent[x] = find(parent[x]);
        }

    void UnionSet(int x, int y) {
        int x_parent = find(x);
        int y_parent = find(y);

        if(rank[x_parent] > rank[y_parent]) {
            parent[y_parent] = x_parent;
        } else if(rank[x_parent] < rank[y_parent]) {
            parent[x_parent] = y_parent;
        } else {
            parent[x_parent] = y_parent;
            rank[y_parent]++;
        }
    }
};

int lcm(int a, int b) {
    return (a / gcd(a, b)) * b;
}
void solve() {
   string a,b,c;
    cin>>a>>b>>c;
    int n = a.size();
    int m = b.size();

    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
    for (int i = 0; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            if (i == 0 && j == 0) {
                dp[i][j] = 0;
            } else if (i == 0) {
                dp[i][j] = dp[i][j - 1] + (b[j - 1] != c[i + j - 1]);
            } else if (j == 0) {
                dp[i][j] = dp[i - 1][j] + (a[i - 1] != c[i + j - 1]);
            } else {
                dp[i][j] = min(
                    dp[i - 1][j] + (a[i - 1] != c[i + j - 1]),
                    dp[i][j - 1] + (b[j - 1] != c[i + j - 1])
                );
            }
        }
    }

    cout << dp[n][m] << endl;
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("input1.txt", "r", stdin);
    freopen("output1.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
int power(int A, int expo)
{
    if (expo == 0)
        return 1;
    int res = power(A, expo / 2);
    if (expo % 2)
        return res * res * A;
    else
        return res * res;
}
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int fact(int x)
{
    if (x == 1 || x == 0)
        return 1;
    return (x * fact(x - 1));
}
class UnionFind{
    private: vector<int> parent,rank;
    public:
        UnionFind(int n){
            rank.assign(n,0);
            parent.assign(n,0);
            iota(parent.begin(),parent.end(),0);
        }
        int find(int x) {
            if(parent[x] == x)
                return x;

            return parent[x] = find(parent[x]);
        }

    void UnionSet(int x, int y) {
        int x_parent = find(x);
        int y_parent = find(y);

        if(rank[x_parent] > rank[y_parent]) {
            parent[y_parent] = x_parent;
        } else if(rank[x_parent] < rank[y_parent]) {
            parent[x_parent] = y_parent;
        } else {
            parent[x_parent] = y_parent;
            rank[y_parent]++;
        }
    }
};

int lcm(int a, int b) {
    return (a / gcd(a, b)) * b;
}
int dp[10001][10001];
int solveRec(int i, int j,string &a, string &b, string &c) {
    if (i == a.size() && j == b.size()) return 0;
    if (dp[i][j] != -1) return dp[i][j];

    int k = i + j;
    int result = INT_MAX;

    if (i < a.size()) {
        result = min(result, solveRec(i + 1, j, a, b, c) + (a[i] != c[k]));
    }

    if (j < b.size()) {
        result = min(result, solveRec(i, j + 1, a, b, c) + (b[j] != c[k]));
    }

    return dp[i][j] = result;
}
void solve() {
   string a,b,c;
   cin>>a>>b>>c;
   memset(dp,-1,sizeof(dp));
   cout<<solveRec(0,0,a,b,c)<<'\n';
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("input1.txt", "r", stdin);
    freopen("output1.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

Answer: 1


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include<bits/stdc++.h>
using namespace std;

int minChanges(string &a, string &b, string &c) {
    int n = a.length(), m = b.length();
    vector<int> prev(m + 1, 0), curr(m + 1, 0);

    // Initialize base cases
    for (int j = 0; j <= m; ++j) {
        prev[j] = j; // Only use characters from `b`
    }

    for (int i = 0; i <= n; ++i) {
        curr[0] = i; // Only use characters from `a`

        for (int j = 0; j <= m; ++j) {
            if (i == 0 && j == 0) continue; // Base case already handled
            int k = i + j - 1; // Current index in `c`

            curr[j] = INT_MAX; // Initialize to a large value

            if (i > 0 && a[i - 1] == c[k]) { // Match with `a`
                curr[j] = min(curr[j], prev[j]);
            } else if (i > 0) { // Mismatch with `a`
                curr[j] = min(curr[j], prev[j] + 1);
            }

            if (j > 0 && b[j - 1] == c[k]) { // Match with `b`
                curr[j] = min(curr[j], curr[j - 1]);
            } else if (j > 0) { // Mismatch with `b`
                curr[j] = min(curr[j], curr[j - 1] + 1);
            }
        }

        // Swap `prev` and `curr`
        swap(prev, curr);
    }

    return prev[m];
}

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

    int t;
    cin >> t;
    while (t--) {
        string a, b, c;
        cin >> a >> b >> c;
        cout << minChanges(a, b, c) << '\n';
    }

    return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include<bits/stdc++.h>
using namespace std;
int minOperations(string a, string b, string c) {
    int n = a.length(), m = b.length(), l = c.length();
    vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(m + 1, vector<int>(l + 1, INT_MAX)));

    // Base case: If i == n and j == m, cost is 0
    for (int k = 0; k <= l; ++k) {
        dp[n][m][k] = 0;
    }

    // Fill the DP table in reverse (bottom-up)
    for (int i = n; i >= 0; --i) {
        for (int j = m; j >= 0; --j) {
            for (int k = l; k >= 0; --k) {
                if (i == n && j == m) continue; // Already handled base case

                if (i < n && j < m) {
                    if (a[i] == b[j]) {
                        if (a[i] == c[k]) {
                            dp[i][j][k] = min(dp[i + 1][j][k + 1], dp[i][j + 1][k + 1]);
                        } else {
                            dp[i][j][k] = 1 + min(dp[i + 1][j][k + 1], dp[i][j + 1][k + 1]);
                        }
                    } else {
                        if (a[i] == c[k]) {
                            dp[i][j][k] = min(dp[i + 1][j][k + 1], 1 + dp[i][j + 1][k + 1]);
                        } else if (b[j] == c[k]) {
                            dp[i][j][k] = min(1 + dp[i + 1][j][k + 1], dp[i][j + 1][k + 1]);
                        } else {
                            dp[i][j][k] = 1 + min(dp[i + 1][j][k + 1], dp[i][j + 1][k + 1]);
                        }
                    }
                } else if (i < n) {
                    if (a[i] == c[k]) {
                        dp[i][j][k] = dp[i + 1][j][k + 1];
                    } else {
                        dp[i][j][k] = 1 + dp[i + 1][j][k + 1];
                    }
                } else if (j < m) {
                    if (b[j] == c[k]) {
                        dp[i][j][k] = dp[i][j + 1][k + 1];
                    } else {
                        dp[i][j][k] = 1 + dp[i][j + 1][k + 1];
                    }
                }
            }
        }
    }

    return dp[0][0][0]; // Final result
}

int main(){
    int t;
    cin>>t;
    while(t--){

       string a,b,c;
       cin>>a>>b>>c;

     cout<<   minOperations(a,b,c);

   cout<<endl;

    }
    return 0;
}

Answer: 1


    #include "bits/stdc++.h"

    using namespace std;

    string c;

    int solve(string a, string b){

        int arr[a.length()+1][b.length()+1];

        for(int i=0; i<=a.length(); i++){

            for(int j=0; j<=b.length(); j++){

                if(i == 0 && j == 0) arr[i][j] = 0;

                else if (i == 0 && j != 0){

                    if(b[j-1] == c[j-1]) arr[i][j] = arr[i][j-1];

                    else arr[i][j] = arr[i][j-1]+1;

                } else if(i != 0 && j == 0){

                    if(a[i-1] == c[i-1]) arr[i][j] = arr[i-1][j];

                    else arr[i][j] = arr[i-1][j]+1;

                } else{

                    int ans_1, ans_2;

                    if(a[i-1] == c[i+j-1]) ans_1 = arr[i-1][j];

                    else ans_1 = arr[i-1][j]+1;

                    if(b[j-1] == c[i+j-1]) ans_2 = arr[i][j-1];

                    else ans_2 = arr[i][j-1]+1;

                    arr[i][j] = min(ans_1,ans_2);

                }

            }

        }

        return arr[a.length()][b.length()];

    }

    int main(){

        int t; cin >> t;

        while(t--){

            string a,b; cin >> a >> b >> c;

            cout << solve(a,b) << endl;

        }

        return 0;

    }

#include "bits/stdc++.h"

using namespace std;

int solve(string a, string b, string c){

    int arr[a.length()][b.length()];

    for(int i=0; i<a.length(); i++){

        for(int j=0; j<b.length(); j++){

            int ans_1=a.length()+b.length(), ans_2=a.length()+b.length();

            if(i != 0 and a[i] == c[i+j]) ans_1 = arr[i-1][j];

            else ans_1 = arr[i-1][j]+1;

            if(j != 0 and b[j] == c[i+j]) ans_2 = arr[i][j-1];

            else ans_2 = arr[i][j-1]+1;

            if(i != 0 and j != 0) arr[i][j] = min(ans_1,ans_2);

        }

    }

    return arr[a.length()-1][b.length()-1];

}

int main(){

    int t; cin >> t;

    while(t--){

        string a,b,c; cin >> a >> b >> c;

        cout << solve(a,b,c) << endl;

    }

    return 0;

}

Answer: 1


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

void solve() {
	string a, b, c;
	cin >> a >> b >> c;
	int n = a.size(), m = b.size();
	int N = n + m;
	vector dp(N + 1, vector<int> (n + 1, 2005));
	dp[0][0] = 0;
	for (int i = 1; i <= N; i++) {
		for (int j = 0; j <= min(n, i); j++) {
			if (j + 1 <= n) dp[i][j + 1] = min(dp[i][j + 1],
				dp[i - 1][j] + (c[i - 1] != a[j]));
			dp[i][j] = min(dp[i][j], dp[i - 1][j] + (c[i - 1] != b[i - j - 1]));
		}
	}
	int ans = dp[N][n];
	cout << ans << "\n";
}

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

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}

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

void solve() {
	string a, b, c;
	cin >> a >> b >> c;
	int n = a.size(), m = b.size();
	int N = n + m;
	vector dp(N + 1, vector<int> (n + 1, 1005));
	dp[0][0] = 0;
	for (int i = 1; i <= N; i++) {
		for (int j = 0; j <= min(n, i); j++) {
			if (j + 1 <= n) dp[i][j + 1] = min(dp[i][j + 1], dp[i - 1][j] + (c[i - 1] != a[j]));
			dp[i][j] = min(dp[i][j], dp[i - 1][j] + (c[i - 1] != b[i - j - 1]));
		}
	}
	int ans = 1005;
	for (int i = 0; i <= n; i++) {
		ans = min(ans, dp[N][i]);
	}
	cout << ans << "\n";
}

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

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}

Answer: 1


#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
map<int,int> primes;
vector<char> good={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

void dfs(vector<bool>&vis,char node,vector<vector<char>>&adj) {
    for(int i=0;i<adj[int(node-'a')].size();i++){
        if(!vis[adj[int(node-'a')][i]]){
            vis[adj[int(node-'a')][i]]=true;
            cout<<adj[int(node-'a')][i];
            dfs(vis,adj[int(node-'a')][i],adj);
        }
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    string a,b,c;
    cin>>a>>b>>c;
    int n=a.size(),m=b.size();
    vector<vector<int>> dp(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++){
        dp[i][0]=dp[i-1][0]+(a[i-1]!=c[i-1]);
    }
    for(int i=1;i<=m;i++){
        dp[0][i]=dp[0][i-1]+(b[i-1]!=c[i-1]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            dp[i][j]=min((dp[i][j-1]+(b[j-1]!=c[i+j-1])),(dp[i-1][j]+(a[i-1]!=c[i+j-1])));
        }
    }
    cout<<dp[n][m]<<endl;
}

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
map<int,int> primes;
vector<char> good={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

void dfs(vector<bool>&vis,char node,vector<vector<char>>&adj) {
    for(int i=0;i<adj[int(node-'a')].size();i++){
        if(!vis[adj[int(node-'a')][i]]){
            vis[adj[int(node-'a')][i]]=true;
            cout<<adj[int(node-'a')][i];
            dfs(vis,adj[int(node-'a')][i],adj);
        }
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin>>t;
    while(t--){
    string a,b,c;
    cin>>a>>b>>c;
    int n=a.size(),m=b.size();
    vector<vector<int>> dp(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++){
        dp[i][0]=dp[i-1][0]+(a[i-1]!=c[i-1]);
    }
    for(int i=1;i<=m;i++){
        dp[0][i]=dp[0][i-1]+(b[i-1]!=c[i-1]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            dp[i][j]=min((dp[i][j-1]+(b[j-1]!=c[i+j-1])),(dp[i-1][j]+(a[i-1]!=c[i+j-1])));
        }
    }
    cout<<dp[n][m]<<endl;
    }
}

Answer: 2


#include <bits/stdc++.h>
using namespace std;
int main() {
    int tt;
    cin >> tt;
    while (tt--) {
        string A, B, C;
        cin >> A >> B >> C;
        int nA = int(A.size());
        int nB = int(B.size());
        vector<vector<int>> dp(nA + 1, vector<int>(nB + 1, nA + nB + 1));
        dp[0][0] = 0;
        for (int i = 0; i <= nA; i++) {
            for (int j = 0; j <= nB; j++) {
                if (i < nA) {
                    dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + (A[i] != C[i + j]));
                }
                if (j < nB) {
                    dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + (B[j] != C[i + j]));
                }
            }
        }
        cout << dp[nA][nB] << endl;
    }
}

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    int tt;
    cin >> tt;
    while (tt--) {
        string a, b, c;
        cin >> a >> b >> c;

    }
}

Answer: 1