Problem: 2050E - Three Strings
Language: python

Solution 1 (runtime: 1202 ms):
# author 
# Kidus Guade

import sys
import random
from types import GeneratorType
from sys import stdin,stdout
from math import gcd,floor,sqrt,log, ceil
from collections import defaultdict, Counter, deque
from bisect import bisect_left,bisect_right, insort_left, insort_right
def ints(): return map(int, sys.stdin.readline().strip().split())
def li(): return list(map(int, sys.stdin.readline().strip().split()))
def string(): return sys.stdin.readline().strip()
def get_int(): return int(sys.stdin.readline().strip())
def li_strings(): return list(map(str, sys.stdin.readline().strip().split()))


def bootstrap(f, 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 primeFactors(n):
    
    i = 2
    primfac = []
    while i * i <= n:
        while n % i == 0:
            primfac.append(i)
            n = n / i
        i = i + 1
    if n > 1:
        primfac.append(int(n))
    return primfac
def prime_sieve(n):
    is_prime = [True for _ in range(n + 1)]
    is_prime[0] = is_prime[1] = False
    i = 2
    while i * i <= n:
        if is_prime[i]:
            j = i * i
            while j <= n:
                is_prime[j] = False
                j += i
        i += 1
    return is_prime
def find_divisors(number):
    divisors = []
    for i in range(1, int(number**0.5) + 1):
        if number % i == 0:
            divisors.append(i)
            if i != number // i:
                divisors.append(number // i)
    return divisors    
def solve():
    a = string()
    b = string()
    c = string()
    dp = [[float("inf") for _ in range(len(a) + 1)] for _ in range(len(c) + 1)]
    for i in range(len(a) + 1):
        dp[len(c)][i] = 0
  
    for i in range(len(c) -1, -1, -1):
        for j in range(len(a) + 1):
            if j > i:
                continue
            k = i - j
           
            vv1, vv2= float("inf"), float("inf")
            if j  < len(a):
                if a[j] == c[i]:
                    vv1 = dp[i + 1][j +1]
                else:
                    vv1 = 1 + dp[i + 1][j + 1]
            if k < len(b):
                if b[k] == c[i]:
                    vv2 = dp[i + 1][j]
                else:
                    vv2 = 1 + dp[i + 1][j]
            
            dp[i][j] = min(min(vv1, vv2), dp[i][j])
    return dp[0][0]
    a = string()
    b = string()
    c = string()

    

   
    memo = [[float('inf') for _ in range(len(c) + 1)] for _ in range(len(a) + 1)]
    
 
    for i in range(len(a) + 1):
        memo[i][len(c)] = 0

  
    for k in range(len(c) - 1, -1, -1):
        for i in range(len(a) + 1):
            if i < len(a):
                if a[i] == c[k]:
                    vv = memo[i + 1][k + 1]
                else:
                    vv = 1 + memo[i + 1][k + 1]
                memo[i][k] = min(memo[i][k], vv)

            if k - i < len(b):
                if b[k - i] == c[k]:
                    vv = memo[i][k + 1]
                else:
                    vv = 1 + memo[i][k + 1]
                memo[i][k] = min(memo[i][k], vv)

    # The result is stored in memo[0][0]
    return memo[0][0]
    
    

# Call the solve function
# result = solve()
# print(result)
    
        
                



    
    # return dp[len(a)][len(c)]

   

    memo = [[0 for _ in range(len(c) + 1)] for _ in range(len(a) + 1)]
    def dp(i,k):
        if k == len(c):
            yield 0
        if memo[i][k]:
            yield memo[i][k]
        val = float('inf')
        if i < len(a):
            if a[i] == c[k]:
                vv = dp(i + 1,k + 1)
                
            else:
                vv = dp(i + 1,k + 1)
                vv += 1
            val = min(val, vv)
               
        if k - i < len(b):
            if b[k - i ] == c[k]:
                vv = dp(i,  k + 1)
              
            else:
                vv = dp(i, k + 1)
                vv += 1

            val = min(val, vv)
        memo[i][k] = val
        yield memo[i][k]
    return dp(0,0)

    
  


    
    
    
if __name__ == "__main__":
    for _ in range(get_int()):
        print(solve())

Solution 2 (runtime: 484 ms):
#include <bits/stdc++.h>

using namespace std;

 

#define ll long long

#define ull unsigned long long 

#define int long long int

 

#define init ios_base::sync_with_stdio(false); cin.tie(NULL);

#define no cout << "NO\n"

#define yes cout << "YES\n"

#define mod 1000000007

#define endd cout << "\n"

#define endl "\n"

#define came cout<<"came\n";

 

#ifndef ONLINE_JUDGE

#define debug(x) cerr << #x <<" "; __print(x); cerr << endl;

#define start_T auto start = std::chrono::high_resolution_clock::now();

#define end_T auto end = std::chrono::high_resolution_clock::now(); \

chrono::duration<double> duration = end - start; \

cout << "Time taken: "<<duration.count()<<" seconds"<<endl;

#else 

#define debug(x)

#define start_T

#define end_T

#endif

//----------------------------------------------------------------------------------------------  

template<class T>

void __print(T t){cerr<<t<<" ";}

template<class T>

void in(T a[],int n){for(int i=0;i<n;i++) cin>>a[i];}

template<class T> 

void out(T a[], int x){for(int i = 0; i < x; i++){cout << a[i] << " "; } cout << endl;}

template<class T> 

void in(vector<T>& a, int n){for(int i = 0; i < n; i++){ T x; cin >> x; a.push_back(x);}}

template<class T>

void in(vector<vector<T>>& a,int n,int m){vector<T> tp;for(int i=0;i<n;i++){tp.clear();in(tp,m);a.push_back(tp);}}

template<class T>

void out(vector<T> a){for(auto i : a)cout << i << " ";cout << endl;}

struct pair_hash{

template <class T1, class T2>

std::size_t operator()(const pair<T1, T2>& pair) const {return std::hash<T1>()(pair.first) ^ (std::hash<T2>()(pair.second) << 1);}};

class DSU{

 public:

    vector<int> parent,rank,size;

    DSU(int n){

         // rank.resize(n+1,0);

         parent.resize(n+1);

         size.resize(n+1,1);

         iota(parent.begin(),parent.end(),0);

    }

    //finding ultimate parent()

    int fup(int node){

         if(node == parent[node]) return node;

         // path compression

         return parent[node] = fup(parent[node]);

    }

    // union by rank()

    void joinr(int u,int v){

         int p1 = fup(u), p2 = fup(v);

         if(p1==p2) return;

         else if(rank[p1]>rank[p2]){

             parent[p2]=p1;

         }

         else if(rank[p2]>rank[p1]){

             parent[p1]=p2;

         }

         else{

            parent[p1]=p2;

            //we ar attaching component p1 to p2

            rank[p2]++;

         }

    }

    // union by size()

    void joins(int u,int v){

        int p1 = fup(u);

        int p2 = fup(v);

        if(p1==p2) return;

        else if(size[p1]>size[p2]) size[p1]+=size[p2],parent[p2]=p1;

        else size[p2]+=size[p1],parent[p1]=p2;

}};

class SEG{

 public:

    vector<int> seg;

    vector<int> arr;

    vector<int> lazy;

    SEG(int n){

       this->seg = vector<int>(n*4+1,0);

       this->lazy = vector<int>(n*4+1,0);

       this->arr.clear();

    }

    void build(){

        if(this->arr.size()==0) return;

       this->build(0,0,this->arr.size()-1);

    }

    int query(int l,int r){

         return this->query(0,0,arr.size()-1,l,r);

    }

    // Builds a Seg Tree

    int build(int ind,int lo,int hi){

         if(lo==hi){

             return this->seg[ind] = this->arr[lo];

         }

         int mid = (lo+hi)/2;

         return this->seg[ind] = __gcd(build(2*ind+1,lo,mid),build(2*ind+2,mid+1,hi));

    }

    int query(int ind,int lo,int hi,int l,int r){

         //complete lying

         // l --- low -- high --- r

         if(lo>=l && hi<=r) return this->seg[ind];

         //Not overlap

         // lo -- hi -- l -- r [or] l -- r -- lo -- hi

         if(hi<l || lo>r) return 0;

         //Semi Overlap

         int mid = (lo+hi)/2;

         return __gcd(query(ind*2+1,lo,mid,l,r),query(ind*2+2,mid+1,hi,l,r));

    }

    // Updates the I'th ind value 

    void update(int segind,int lo,int hi,int val,int ind){

         if(lo==hi && lo==ind){

             this->seg[segind] = val;

             return;

         }

         int mid = (lo+hi)/2;

         if(lo<=ind&&mid>=ind) update(2*segind+1,lo,mid,val,ind);

         else update(2*segind+2,mid+1,hi,val,ind);

         this->seg[segind] = max(this->seg[segind*2+1],this->seg[segind*2+2]);

    }

    //update Lazy

    void updatel(int ind,int lo,int hi,int l,int r,int val){

        // updating the pendings 

        if(this->lazy[ind]!=0){

             this->seg[ind] = (hi-lo+1)*this->lazy[ind];

             if(hi!=lo){

                this->lazy[2*ind+1]=this->lazy[2*ind+2]=this->lazy[ind];

             }

             this->lazy[ind]=0;

        }



        if(lo>r || hi<l || lo>hi) return;

        // l -- lo -- hi -- r

        if(lo>=l && hi<=r){

             this->seg[ind] += (hi-lo+1) * val;

             if(lo!=hi){

                 this->lazy[2*ind+1]+= val;

                 this->lazy[2*ind+2]+= val;

             }

        }

        

        int mid = (lo+hi)/2;

        updatel(ind*2+1,lo,mid,l,r,val);

        updatel(ind*2+2,mid+1,hi,l,r,val);

        this->seg[ind] = this->seg[ind*2+1] + this->seg[ind*2+2];

    }

    int queryl(int ind,int lo,int hi,int l,int r){

        // updating the pendings 

        if(this->lazy[ind]!=0){

             this->seg[ind] = (hi-lo+1)*this->lazy[ind];

             if(hi!=lo){

                this->lazy[2*ind+1]=this->lazy[2*ind+2]=this->lazy[ind];

             }

             this->lazy[ind]=0;

        }



        if(lo>r || hi<l || lo>hi) return 0;

        // l -- lo -- hi -- r

        if(lo>=l && hi<=r){

             return this->seg[ind];

        }

        int mid = (lo+hi)/2;

        return queryl(ind*2+1,lo,mid,l,r)+queryl(ind*2+2,mid+1,hi,l,r);

    }};

inline int fib(int n) {const double phi = (1 + sqrt(5)) / 2;const double psi = (1 - sqrt(5)) / 2;return round((pow(phi, n) - pow(psi, n)) / sqrt(5));}

inline int gcd(int A, int B){while(A>0&&B>0){if(A>B) A%=B;else B%=A;}return ((A==0)?B:A);}

inline int lcm(int A, int B) {return ((A * B) / (gcd(A, B)));}

inline bool isprime(int X) {if(X==1) return 0;if (X == 2) return true;for (int i = 2; i <= sqrt(X); i++) {if ((X % i) == 0)return false;}return true;}

// int Mod(string &a,int k){int rem=0;for(int i=0;i<a.size();i++){rem = (rem*10+(a[i]-'0'))%k;}return rem;}

class sieve{

  public:

  int n;

  vector<bool> is_prime;

  vector<int> primes;  

  sieve(int n){

     this->n=n;

     is_prime.resize(n+1,true);

     is_prime[0] = is_prime[1] = false;

     for(int i=2;i<=n;i++){

     if(is_prime[i]){

        primes.push_back(i);

        for(int j=i*i;j<=n;j+=i)

            is_prime[j] = false;

    }

   }

  }

  bool fun(int ind){

     return is_prime[ind];

  } };

int pow(int a,int b){if(b==0) return 1;int res=pow(a,b/2);if(b%2) return ((((res*res)%mod)*a)%mod);else return ((res*res)%mod);}

int modInverse(int a,int p){int res=1,exp=p-2;while(exp){if(exp%2)res=(1LL*res*a)%p;a=(1LL*a*a)%p; exp/=2;}return res;}

//-------------------------------------------------UDF------------------------------------------------

map<tuple<int,int,int>,int> dp;

int fun(string &a,string &b,string &c,int i,int j,int k){

     if(i<0&&j<0&&k<0) return 0;

     if(i<0){

         while(j>=0&&k>=0){

            if(b[j]==c[k]) j--,k--;

            else break;

         }

         if(k<0) return 0;

         return (k+1);

     }

     if(j<0){

         while(i>=0&&k>=0){

            if(a[i]==c[k]) i--,k--;

            else break;

         }

         if(k<0) return 0;

         return (k+1);

     }

     if(dp.find({i,j,k})!=dp.end()) return dp[{i,j,k}];

     int res = INT_MAX;

     res = min({res,fun(a,b,c,i,j-1,k-1)+(b[j]!=c[k]),fun(a,b,c,i-1,j,k-1)+(a[i]!=c[k])});

     return dp[{i,j,k}] = res;

}

signed main(){  

  init;start_T;

  #ifndef ONLINE_JUDGE

  freopen("input.txt", "r", stdin);

  freopen("output.txt", "w", stdout);

  freopen("error.txt", "w", stderr);  

  #endif

  ll _=1;

  cin>>_;

  while(_--){

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

     dp.clear();

     cout<<fun(a,b,c,a.size()-1,b.size()-1,c.size()-1)<<endl;

  }

  end_T;

}