কম্পিউটার টিউটোরিয়াল

C++-এ সব গুড স্ট্রিং খুঁজুন (Find All Good Strings)


দুটি স্ট্রিং s1, s2 (দৈর্ঘ্য n) এবং evil স্ট্রিং দেওয়া আছে। কতগুলো "গুড" স্ট্রিং আছে? গুড স্ট্রিং: দৈর্ঘ্য n, s1 >= alphabetically >= s2, evil সাবস্ট্রিং হিসেবে নেই। মডুলো ১০^৯+৭।

উদাহরণ: n=2, s1="bb", s2="db", evil="a" -> ৫১। 'b' দিয়ে ২৫, 'c' দিয়ে ২৫, 'd' দিয়ে ১ (db) = ৫১।

সমাধানের ধাপসমূহ

  • KMP অটোমেটন (tr[M+1][26]) বানান evil-র জন্য।
  • DP[i][j][tight]: i পজিশন, j = evil-এ ম্যাচ করা প্রিফিক্স দৈর্ঘ্য, tight = s-এ বাউন্ডেড কিনা।
  • বটম-আপ DP: dp[n][0][1] = 1। i=n-1 থেকে ০, সব j, k (অক্ষর), l (tight) için ট্রানজিশন।
  • solve(n, s, evil): s-এ বাউন্ডেড স্ট্রিংগুলোর সংখ্যা।
  • ফলাফল = solve(n, s2, evil) - solve(n, s1-1, evil) (মডুলো)।

C++ কোড উদাহরণ

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const int N = 500, M = 50;
int dp[N+1][M+1][2];
int tr[M+1][26];
const lli m = 1e9 + 7;

class Solution {
public:
    int add(lli a, lli b) { return ((a % m) + (b % m)) % m; }
    lli solve(int n, string s, string e) {
        reverse(e.begin(), e.end());
        memset(tr, 0, sizeof(tr));
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < e.size(); i++) {
            string f = e.substr(0, i);
            for (int j = 0; j < 26; j++) {
                string ns = f + (char)(j + 'a');
                for (int k = i+1;; k--)
                    if (ns.substr(i+1-k) == e.substr(0, k)) { tr[i][j] = k; break; }
            }
        }
        int m_len = e.size();
        for (int i = 0; i <= n; i++)
            for (int j = 0; j < m_len; j++)
                dp[i][j][0] = dp[i][j][1] = 0;
        dp[n][0][1] = 1;
        for (int i = n-1; i >= 0; i--)
            for (int j = 0; j < e.size(); j++)
                for (int k = 0; k < 26; k++)
                    for (int l : {0, 1}) {
                        int nl;
                        if (k > s[i]-'a') nl = 0;
                        else if (k < s[i]-'a') nl = 1;
                        else nl = l;
                        dp[i][tr[j][k]][nl] = add(dp[i][tr[j][k]][nl], dp[i+1][j][l]);
                    }
        lli ret = 0;
        for (int i = 0; i < e.size(); i++) ret = add(ret, dp[0][i][1]);
        return ret;
    }
    int findGoodStrings(int n, string s1, string s2, string evil) {
        bool ok = 1;
        for (int i = 0; i < s1.size() && ok; i++) ok = (s1[i] == 'a');
        if (!ok) {
            for (int i = s1.size()-1; i >= 0; i--)
                if (s1[i] != 'a') { s1[i]--; break; }
                else s1[i] = 'z';
        }
        int left = ok ? 0 : solve(n, s1, evil);
        int right = solve(n, s2, evil);
        return (right - left + m) % m;
    }
};

int main() {
    Solution ob;
    cout << ob.findGoodStrings(2, "bb", "db", "a");
    return 0;
}

ইনপুট

2, "bb", "db", "a"

আউটপুট

51
  1. C++ ব্যবহার করে সব ডুপ্লিকেট সাবট্রি বের করা

  2. C++-এ গ্রাফে সব ফরওয়ার্ড এজ (Forward Edges) খুঁজে বের করা

  3. C++-এ স্ট্রিং এর অ্যারে (C++ Array of Strings)

  4. C++ প্রোগ্রাম: দ্বিঘাত সমীকরণের মূল (Roots) নির্ণয়