Problem: 2050E - Three Strings
Language: python

Solution 1 (runtime: 265 ms):
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)


Solution 2 (runtime: 234 ms):
from functools import *
from itertools import *
from collections import *
from math import *
from bisect import *
from heapq import *

def factors(n):
    i = 1
    res = []
    while i <= sqrt(n):
        if (n % i == 0):
            if (n / i == i):
                res.append(i)
            else:
                res.append(i)
                res.append(n//i)
        i = i + 1
    return res

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

def largest_prime_factor(n):
    i = 2
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
    return n

def sieve(n):
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * p, n+1, p):
                prime[i] = False
        p += 1

    return prime

MOD=10**9+7
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]
 
    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]
 
    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]
 
    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]
 
class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)
 
    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

for _ in range(int(input())):
    a = list(input())
    b = list(input())
    c = list(input())

    mask = 0

    dp = [[inf]*(len(b)+1) for _ in range(len(a)+1)]

    for ai in range(len(a), -1, -1):
        for bi in range(len(b), -1, -1):
            i = ai+bi
            if i>=len(c):
                dp[ai][bi] = 0
                continue
            
            ago = inf
            bgo = inf

            if ai<len(a):
                ago = int(a[ai]!=c[i]) + dp[ai+1][bi]
            if bi<len(b):
                bgo = int(b[bi]!=c[i]) + dp[ai][bi+1]
            dp[ai][bi] = min(ago, bgo)
    print(dp[0][0])