Problem: 2050E - Three Strings
Language: C++17 (GCC 7-32)

Previous submission (verdict: Time limit exceeded on test 6):


#include <bits/stdc++.h>
using namespace std;
#define read(type) readInt<type>() // Fast read
#define int long long
#define nL "\n"

#define vi vector<int>
#define aint(x) (x).begin(), (x).end()
#define umap unordered_map
#define uset unordered_set
#define MOD 1000000007
#define imax INT_MAX
#define imin INT_MIN
#define exp 1e9
#define sz(x) (int((x).size()))
#define pq_max priority_queue<int>
#define pq_min priority_queue<int, vi, greater<int>>
#define bug(...) __f(#__VA_ARGS__, __VA_ARGS__)

/* FUNCTIONS */
#define f(i, s, e) for (int i = s; i <= e; i++)
#define rf(i, e, s) for (int i = e; i >= s; i--)

/* PRINTS */
template <class T>
void print_v(vector<T> &v)
{
    cout << "{";
    for (auto x : v)
        cout << x << ",";
    cout << "\b}";
}

template <class T>
void print_2d(vector<vector<T>> &v)
{
    cout << "\n";
    for (auto x : v)
    {
        for (auto y : x)
            cout << y << " ";
        cout << "\n";
    }
}

void yes() { cout << "YES\n"; }
void no() { cout << "NO\n"; }

/* UTILS */
#define MOD 1000000007
#define PI 3.1415926535897932384626433832795
#define read(type) readInt<type>() // Fast read
template <typename T>
T readInt()
{
    T n = 0, sign = 1;
    char c;
    while (isspace(c = getchar()))
        ;
    if (c == '-')
        sign = -1;
    else
        n = c - '0';
    while (isdigit(c = getchar()))
        n = n * 10 + c - '0';
    return sign * n;
}
template <typename T>
T pow(T a, T b)
{
    if (b == 0)
        return 1;
    if (b == 1)
        return a % MOD;
    T t = pow(a, b / 2);
    t = (t * t) % MOD;
    if (b % 2)
        return (t * a) % MOD;
    return t;
}

template <typename T>
T minm(T a, T b)
{
    if (a < b)
        return a;
    return b;
}
template <typename T>
T maxm(T a, T b)
{
    if (a > b)
        return a;
    return b;
}
template <typename T>
T gcd(T a, T b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

template <typename T>
T lcm(T a, T b) { return a / gcd(a, b) * b; }

string to_upper(string a)
{
    for (int i = 0; i < (int)a.size(); ++i)
        if (a[i] >= 'a' && a[i] <= 'z')
            a[i] -= 'a' - 'A';
    return a;
}
string to_lower(string a)
{
    for (int i = 0; i < (int)a.size(); ++i)
        if (a[i] >= 'A' && a[i] <= 'Z')
            a[i] += 'a' - 'A';
    return a;
}
bool Isprime(int a)
{
    if (a == 1)
        return 0;
    for (int i = 2; i <= round(sqrt(a)); ++i)
        if (a % i == 0)
            return 0;
    return 1;
}

void solve();

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

    int t;
    t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

int rec_sol(int idx1, int idx2, string &a, string &b, string &c)
{
    int n = a.size();
    int m = b.size();
    int o = c.size();
    if (idx1 == n && idx2 == m)
    {
        return 0;
    }

    if (idx1 == n)
    {
        // do manual check
        int cnt = 0;
        f(i, idx2, m - 1)
        {
            if (b[i] != c[i + idx1])
                cnt++;
        }

        return cnt;
    }

    if (idx2 == m)
    {
        // do manual check
        int cnt = 0;
        f(i, idx1, n - 1)
        {
            if (a[i] != c[i + idx2])
                cnt++;
        }

        return cnt;
    }

    int c_idx = idx1 + idx2;
    // both match
    if (a[idx1] == c[c_idx] && b[idx2] == c[c_idx])
    {
        return minm(rec_sol(idx1 + 1, idx2, a, b, c), rec_sol(idx1, idx2 + 1, a, b, c));
    }
    // one match
    else if (a[idx1] == c[c_idx])
    {
        // one match
        return minm(rec_sol(idx1 + 1, idx2, a, b, c), 1 + rec_sol(idx1, idx2 + 1, a, b, c));
    }
    else if (b[idx2] == c[c_idx])
    {
        return minm(rec_sol(idx1, idx2 + 1, a, b, c), 1 + rec_sol(idx1 + 1, idx2, a, b, c));
    }
    // no match
    else
        return 1 + minm(rec_sol(idx1 + 1, idx2, a, b, c), rec_sol(idx1, idx2 + 1, a, b, c));
}

int dp_sol(string &a, string &b, string &c)
{

    int n = a.size();
    int m = b.size();
    int o = c.size();

    int dp[n + 1][m + 1];
    memset(dp, 0, sizeof(dp));

    // manual check for idx1 = n

    rf(idx2, m - 1, 0)
    {
        if (b[idx2] == c[idx2 + n])
        {
            dp[n][idx2] = dp[n][idx2 + 1];
        }
        else
        {
            dp[n][idx2] = 1 + dp[n][idx2 + 1];
        }
    }

    // manual check for idx2 = m

    rf(idx1, n - 1, 0)
    {
        if (a[idx1] == c[idx1 + m])
        {
            dp[idx1][m] = dp[idx1 + 1][m];
        }
        else
        {
            dp[idx1][m] = 1 + dp[idx1 + 1][m];
        }
    }

    rf(idx1, n - 1, 0)
    {
        rf(idx2, m - 1, 0)
        {
            int c_idx = idx1 + idx2;
            // int c_idx = idx1 + idx2;
            if (a[idx1] == c[c_idx])
            {
                // one match
                dp[idx1][idx2] = minm(dp[idx1 + 1][idx2], 1 + dp[idx1][idx2 + 1]);
                continue;
            }
            if (b[idx2] == c[c_idx])
            {
                dp[idx1][idx2] = minm(dp[idx1][idx2 + 1], 1 + dp[idx1 + 1][idx2]);
                continue;
            }

            dp[idx1][idx2] = 1 + minm(dp[idx1 + 1][idx2], dp[idx1][idx2 + 1]);
        }
    }

    return dp[0][0];
}

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

    // cout << "a: " << a << nL;

    cout << rec_sol(0, 0, a, b, c) << nL;

    // cout << dp_sol(a, b, c) << nL;
}


Submission (verdict: Accepted):


#include <bits/stdc++.h>
using namespace std;
#define read(type) readInt<type>() // Fast read
#define int long long
#define nL "\n"

#define vi vector<int>
#define aint(x) (x).begin(), (x).end()
#define umap unordered_map
#define uset unordered_set
#define MOD 1000000007
#define imax INT_MAX
#define imin INT_MIN
#define exp 1e9
#define sz(x) (int((x).size()))
#define pq_max priority_queue<int>
#define pq_min priority_queue<int, vi, greater<int>>
#define bug(...) __f(#__VA_ARGS__, __VA_ARGS__)

/* FUNCTIONS */
#define f(i, s, e) for (int i = s; i <= e; i++)
#define rf(i, e, s) for (int i = e; i >= s; i--)

/* PRINTS */
template <class T>
void print_v(vector<T> &v)
{
    cout << "{";
    for (auto x : v)
        cout << x << ",";
    cout << "\b}";
}

template <class T>
void print_2d(vector<vector<T>> &v)
{
    cout << "\n";
    for (auto x : v)
    {
        for (auto y : x)
            cout << y << " ";
        cout << "\n";
    }
}

void yes() { cout << "YES\n"; }
void no() { cout << "NO\n"; }

/* UTILS */
#define MOD 1000000007
#define PI 3.1415926535897932384626433832795
#define read(type) readInt<type>() // Fast read
template <typename T>
T readInt()
{
    T n = 0, sign = 1;
    char c;
    while (isspace(c = getchar()))
        ;
    if (c == '-')
        sign = -1;
    else
        n = c - '0';
    while (isdigit(c = getchar()))
        n = n * 10 + c - '0';
    return sign * n;
}
template <typename T>
T pow(T a, T b)
{
    if (b == 0)
        return 1;
    if (b == 1)
        return a % MOD;
    T t = pow(a, b / 2);
    t = (t * t) % MOD;
    if (b % 2)
        return (t * a) % MOD;
    return t;
}

template <typename T>
T minm(T a, T b)
{
    if (a < b)
        return a;
    return b;
}
template <typename T>
T maxm(T a, T b)
{
    if (a > b)
        return a;
    return b;
}
template <typename T>
T gcd(T a, T b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

template <typename T>
T lcm(T a, T b) { return a / gcd(a, b) * b; }

string to_upper(string a)
{
    for (int i = 0; i < (int)a.size(); ++i)
        if (a[i] >= 'a' && a[i] <= 'z')
            a[i] -= 'a' - 'A';
    return a;
}
string to_lower(string a)
{
    for (int i = 0; i < (int)a.size(); ++i)
        if (a[i] >= 'A' && a[i] <= 'Z')
            a[i] += 'a' - 'A';
    return a;
}
bool Isprime(int a)
{
    if (a == 1)
        return 0;
    for (int i = 2; i <= round(sqrt(a)); ++i)
        if (a % i == 0)
            return 0;
    return 1;
}

void solve();

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

    int t;
    t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

int rec_sol(int idx1, int idx2, string &a, string &b, string &c)
{
    int n = a.size();
    int m = b.size();
    int o = c.size();
    if (idx1 == n && idx2 == m)
    {
        return 0;
    }

    if (idx1 == n)
    {
        // do manual check
        int cnt = 0;
        f(i, idx2, m - 1)
        {
            if (b[i] != c[i + idx1])
                cnt++;
        }

        return cnt;
    }

    if (idx2 == m)
    {
        // do manual check
        int cnt = 0;
        f(i, idx1, n - 1)
        {
            if (a[i] != c[i + idx2])
                cnt++;
        }

        return cnt;
    }

    int c_idx = idx1 + idx2;
    // both match
    if (a[idx1] == c[c_idx] && b[idx2] == c[c_idx])
    {
        return minm(rec_sol(idx1 + 1, idx2, a, b, c), rec_sol(idx1, idx2 + 1, a, b, c));
    }
    // one match
    else if (a[idx1] == c[c_idx])
    {
        // one match
        return minm(rec_sol(idx1 + 1, idx2, a, b, c), 1 + rec_sol(idx1, idx2 + 1, a, b, c));
    }
    else if (b[idx2] == c[c_idx])
    {
        return minm(rec_sol(idx1, idx2 + 1, a, b, c), 1 + rec_sol(idx1 + 1, idx2, a, b, c));
    }
    // no match
    else
        return 1 + minm(rec_sol(idx1 + 1, idx2, a, b, c), rec_sol(idx1, idx2 + 1, a, b, c));
}

int dp_sol(string &a, string &b, string &c)
{

    int n = a.size();
    int m = b.size();
    int o = c.size();

    int dp[n + 1][m + 1];
    memset(dp, 0, sizeof(dp));

    // manual check for idx1 = n

    rf(idx2, m - 1, 0)
    {
        if (b[idx2] == c[idx2 + n])
        {
            dp[n][idx2] = dp[n][idx2 + 1];
        }
        else
        {
            dp[n][idx2] = 1 + dp[n][idx2 + 1];
        }
    }

    // manual check for idx2 = m

    rf(idx1, n - 1, 0)
    {
        if (a[idx1] == c[idx1 + m])
        {
            dp[idx1][m] = dp[idx1 + 1][m];
        }
        else
        {
            dp[idx1][m] = 1 + dp[idx1 + 1][m];
        }
    }

    rf(idx1, n - 1, 0)
    {
        rf(idx2, m - 1, 0)
        {
            int c_idx = idx1 + idx2;
            // int c_idx = idx1 + idx2;
            // both match
            if (a[idx1] == c[c_idx] && b[idx2] == c[c_idx])
            {
                dp[idx1][idx2] = minm(dp[idx1 + 1][idx2], dp[idx1][idx2 + 1]);
            }

            // one match
            else if (a[idx1] == c[c_idx])
            {
                dp[idx1][idx2] = minm(dp[idx1 + 1][idx2], 1 + dp[idx1][idx2 + 1]);
            }
            else if (b[idx2] == c[c_idx])
            {
                dp[idx1][idx2] = minm(dp[idx1][idx2 + 1], 1 + dp[idx1 + 1][idx2]);
            }

            // no match
            else
            {
                dp[idx1][idx2] = 1 + minm(dp[idx1 + 1][idx2], dp[idx1][idx2 + 1]);
            }
        }
    }

    return dp[0][0];
}

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

    // cout << "a: " << a << nL;

    // cout << rec_sol(0, 0, a, b, c) << nL;

    cout << dp_sol(a, b, c) << nL;
}