Problem: 2050E - Three Strings
Language: c++17 

Solution 1 (runtime: 93 ms):
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define vi vector<int>
#define ar array
#define vvi vector<vector<int> >
#define f(b) for(int i=0;i<b;i++)
#define fj(b) for(int j=0;j<b;j++)
#define fk(b) for(int k=0;k<b;k++)
#define sr(v) sort(v.begin(),v.end())
// #define f(i, a, n) for (int i = a; i < n; i++)
// Header files, namespaces, 
// macros as defined above 
// note : int -> long long wont be supported with pbds
// #include <ext/pb_ds/assoc_container.hpp> 
// #include <ext/pb_ds/tree_policy.hpp> 
// using namespace __gnu_pbds; 
  
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
 

void io()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
 
    freopen("input.txt", "r", stdin);
 
    freopen("output.txt", "w", stdout);
 
    #endif // ONLINE_JUDGE
 
}
 
/*
    stuff you should look for
    * int overflow, array bounds
    * maximum and minimum possible values for init
    * special cases (n=1,2,3 ?)
    * do smth instead of nothing and stay organised
    * write stuff down
*/
 
 
/*
    mistakes section:
    1. Got tle as didn't return the visited result
    2. If possible use separate vector for visited and separate for dp
	3. Visit all possible children then update current dp state
		-> Tried to update while moving to child. This gives wrong answer
		as we cannot make sure that all parents have visited the child state
	4. avoid creating a global vector and then resizing of reallocating new space
	like dp = vvi (n, vi (m))
	or dp.resize(n, vi(m))
	
    learned:
    Try to start from leaf node and then update parent nodes after all are visited.
    Dont forget to return state if already calculated/visited before
*/
long long binpow(long long a, long long b) {
    const int m=1e9+7;
    a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}
void dbg(vi &a,int n=10)
{
    f(n)
        cout<<a[i]<<" ";
    cout<<endl;
}

const int mxN=1e3,di[4]={1,0,-1,0},dj[4]={0,1,0,-1};
const char dc[4]={'D','R','U','L'};

const int MOD = 1000000007;
vi p(mxN),s(mxN,1),wt(mxN,INT_MAX);

const int mxA=1e6+1;
int lpf[mxA+1];
vector<int> pfs;
vi fact(mxA);
void lpf_cal(){
    //how to use : 
    // while(val>1)
    //    val/=lpf[val];
 
    for(int i=2;i<=mxA;i++){
        if(!lpf[i]){
            pfs.push_back(i);
            lpf[i]=i;
        }
        for(auto prime:pfs)
            if(prime<=lpf[i]&& prime*i<=mxA)
                lpf[prime*i] = prime;
            else
                break;

        // for(int j=0;j<pfs.size()&&pfs[j]<=lpf[i]&&pfs[j]*i<=mxA;j++)
        //     lpf[i*pfs[j]]=pfs[j];
    }
}

int find(int x){
    return x^p[x]?p[x]=find(p[x]):x;
}
bool uni(int a,int b)
{
    if((a=find(a))==(b=find(b)))
        return false;
    p[a]=b;
    s[b]+=s[a];
    return 1;
}
int get(int i,int j)
{
    cout<<"? "<<i<<" "<<j<<endl;
    // fflush(stdout);
    int ij;
    cin>>ij;
    return ij;
}
int get_max(int a,int b){
    return a>b?a:b;
}
int get_min(int a, int b){
    return a<b?a:b;
}

// class for a node of the trie
class TrieNode {
public:
    bool endofWord;
    TrieNode* children[26];

    // Constructore to initialize a trie node
    TrieNode()
    {
        endofWord = false;
        for (int i = 0; i < 26; i++) {
            children[i] = nullptr;
        }
    }
};

// class for the Trie implementation
// Trie trie;
// trie.insert(s)
// trie.search(s)
class Trie {
    private:
        TrieNode* root;

    public:
        Trie() { root = new TrieNode(); }

        // Function to insert a word into the trie
        void insert(string word)
        {
            TrieNode* node = root;
            for (char c : word) {
                int index = c - 'a';
                if (!node->children[index]) {
                    node->children[index] = new TrieNode();
                }
                node = node->children[index];
            }
            node->endofWord = true;
        }

        // Function to search a word in the trie
        int search(string word)
        {
            TrieNode* node = root;
            int len=0;
            for (char c : word) {
                int index = c - 'a';
                if (!node->children[index]) {
                    return len;
                }
                node = node->children[index];
                len++;
            }
            return len;
        }

        // Function to check if there is any word in the trie
        // that starts with the given prefix
        bool startsWith(string prefix)
        {
            TrieNode* node = root;
            for (char c : prefix) {
                int index = c - 'a';
                if (!node->children[index]) {
                    return false;
                }
                node = node->children[index];
            }
            return true;
        }

        // Function to delete a word from the trie
        void deleteWord(string word)
        {
            TrieNode* node = root;
            for (char c : word) {
                int index = c - 'a';
                if (!node->children[index]) {
                    return;
                }
                node = node->children[index];
            }
            if (node->endofWord == true) {
                node->endofWord = false;
            }
        }

        // Function to print the trie
        void print(TrieNode* node, string prefix) const
        {
            if (node->endofWord) {
                cout << prefix << endl;
            }
            for (int i = 0; i < 26; i++) {
                if (node->children[i]) {
                    print(node->children[i],
                          prefix + char('a' + i));
                }
            }
        }

        // Function to start printing from the root
        void print() const { print(root, ""); }
};



unordered_map<int,int> prime;

class Solution{

    public:
    string a,b,c;
	int n,m,infi=1e6+2;
	
	Solution(){
	}

    void pre_process(){
    	// implement pre calculations which can be used for all test cases
    }

    void post_process(){
    	// implement post processing which can be used for all test cases
    }

    int helper(int i,int j, vvi &dp){
    	if(i==n&&j==m)
    		return 0;

    	int &ans=dp[i][j];
    	// Memoization
    	if(dp[i][j]!=infi) return ans;
    	if(j==m) return ans=(a[i]!=c[i+j])+helper(i+1,j, dp);
    	if(i==n) return ans=(b[j]!=c[i+j])+helper(i,j+1, dp);
    	return ans=min((a[i]!=c[i+j])+helper(i+1,j, dp), (b[j]!=c[i+j])+helper(i,j+1, dp));
    }

    // void helper_old(int i,int j,int val){
    // 	if(i==n&&j==m){
    // 		ans=min(ans,val);
    // 		return;
    // 	}
    // 	if(i>n||j>m)
    // 		return;

    // 	// condition satify -> increase value otherwise use last
    // 	// move to new state
    // 	if(i<n) helper_old(i+1,j,val+(a[i]!=c[i+j]));
    // 	if(j<m) helper_old(i,j+1,val+(b[j]!=c[i+j]));
    // }
    void solve()
    {
    	cin>>a>>b>>c;
    	n=a.size(),m=b.size();
    	vvi dp(n+1, vi(m+1, infi));
    	// helper_old(0,0,0);
		// cout<<ans<<endl;

		// cout<<(helper(0,0, dp))<<"\n";

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

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


signed main()
{
    int t=1;
    io();
    // int n=2e5+1;
    // vector<bool> is_prime(n+1, true);
    // is_prime[0] = is_prime[1] = false;
    // for (int i = 2; i <= n; i++) {
    //     if (is_prime[i] && (long long)i * i <= n) {
    //         for (int j = i * i; j <= n; j += i)
    //             is_prime[j] = false;
    //     }
    //     if(is_prime[i])
    //         prime[i]=1;
    // }

    cin>>t;
    f(t){
    	Solution a;
        a.pre_process();
        a.solve();
        a.post_process();
    }
    return 0;
}





Solution 2 (runtime: 93 ms):
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define ld long double
#define int long long
#define ll long long
#define len(a) (int)(a.length())
#define pb push_back
#define pii pair<int, int>
typedef vector<int> vi;
typedef vector<vi> vvi;
    
    
void faster(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}
    
int power(long long x, unsigned int y, int p) 
{ 
    int res = 1;     // Initialize result 
    
    x = x % p; // Update x if it is more than or 
                // equal to p
    
    if (x == 0) return 0; // In case x is divisible by p;
    
    while (y > 0) 
    { 
        // If y is odd, multiply x with result 
        if (y & 1) 
            res = (res*x) % p; 
    
        // y must be even now 
        y = y>>1; // y = y/2 
        x = (x*x) % p; 
    } 
    return res; 
} 
    
int gcd(int a, int b)
{
    if(b>a) swap(a,b);

    if(b==0) return a;
    
    return gcd(b,a%b);
}


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

    vvi dp(len(a)+1, vi(len(b)+1, INT_MAX));

    dp[0][0] = 0;

    for(int i=0; i<=len(a); i++)
    {
        for(int j=0; j<=len(b); j++)
        {
            if(i>0)
            {
                dp[i][j] = min(dp[i][j], dp[i-1][j]+(a[i-1]==c[i+j-1]?0:1));
            }
            if(j>0)
            {
                dp[i][j] = min(dp[i][j], dp[i][j-1]+(b[j-1]==c[i+j-1]?0:1));
            }
        }
    }
    cout<<dp[len(a)][len(b)]<<endl;//fhgerghrf
    return;
}
//dfgesrg
int32_t main()
{
    faster();//fdgdgr
    int t;
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}