📜  满足给定条件的子序列数

📅  最后修改于: 2021-05-04 11:05:17             🧑  作者: Mango

给定一个由数字组成的字符串str ,任务是查找可能的4个数字子序列的数量,这些子序列的形式为(x,x,x + 1,x + 1) ,其中x可以在[0, 8]

例子:

方法:

  • 我们将找出从0到8的每个可能x的可能子序列的总数。
  • 对于每个x,请从字符串中删除所有其他数字,但x和x + 1除外,因为它们不会影响答案。
  • 维护前缀Sum数组以计算x + 1位数,直到在字符串中的第i个索引为止。
  • 现在,对于每个大小为K的数字俱乐部(即x),我们都可以用KC2的方式选择两个数字。最后两个数字可以是所有数字(x + 1)中的任意两个数字,其后跟数字俱乐部(使用前缀和数组确定数字)的大小L,因此有LC2种选择方式。总路数= KC2 * LC2。
  • 直到现在,我们可以认为x来自同一个俱乐部,但也可以来自多个俱乐部。因此,我们必须考虑所有可能的球杆对,并将它们的大小相乘,以获得选择前两个数字的方式。对于最后两个数字,方式将保持不变。
  • 为了防止在步骤5中出现计数过多的问题,将只选择可能的方法,其中包括正在考虑的当前球杆,因为在计算先前球杆时已经考虑了其他方法。
  • 为x的所有值添加所有可能的方法,并取Modulo。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#define ll long long int
#define MOD 1000000007
using namespace std;
  
// Function to return the total
// requried sub-sequences
int solve(string test)
{
    int size = test.size();
    int total = 0;
  
    // Find ways for all values of x
    for (int i = 0; i <= 8; i++) {
        int x = i;
  
        // x+1
        int y = i + 1;
        string newtest;
  
        // Removing all unnecessary digits
        for (int j = 0; j < size; j++) {
            if (test[j] == x + 48 || test[j] == y + 48) {
                newtest += test[j];
            }
        }
  
        if (newtest.size() > 0) {
            int size1 = newtest.size();
  
            // Prefix Sum Array for X+1 digit
            int prefix[size1] = { 0 };
            for (int j = 0; j < size1; j++) {
                if (newtest[j] == y + 48) {
                    prefix[j]++;
                }
            }
  
            for (int j = 1; j < size1; j++) {
                prefix[j] += prefix[j - 1];
            }
  
            int count = 0;
            int firstcount = 0;
  
            // Sum of squares
            int ss = 0;
  
            // Previous sum of all possible pairs
            int prev = 0;
  
            for (int j = 0; j < size1; j++) {
                if (newtest[j] == x + 48) {
                    count++;
                    firstcount++;
                }
                else {
  
                    ss += count * count;
  
                    // To find sum of multiplication of all
                    // possible pairs
                    int pairsum = (firstcount * firstcount - ss) / 2;
                    int temp = pairsum;
  
                    // To prevent overcounting
                    pairsum -= prev;
                    prev = temp;
  
                    int secondway = prefix[size1 - 1];
                    if (j != 0)
                        secondway -= prefix[j - 1];
  
                    int answer = count * (count - 1)
                                 * secondway * (secondway - 1);
                    answer /= 4;
                    answer += (pairsum * secondway
                               * (secondway - 1)) / 2;
  
                    // Adding ways for all possible x
                    total += answer;
                    count = 0;
                }
            }
        }
    }
  
    return total;
}
  
// Driver code
int main()
{
    string test = "13134422";
    cout << solve(test) << endl;
  
    return 0;
}


Java
// Java Implementation of above approach 
import java.io.*; 
  
class GFG 
{ 
  
// Function to return the total 
// requried sub-sequences 
static int solve(String test, int MOD) 
{ 
    int size = test.length(); 
    int total = 0; 
  
    // Find ways for all values of x 
    for (int i = 0; i <= 8; i++)
    { 
        int x = i; 
  
        // x+1 
        int y = i + 1; 
        String newtest = ""; 
  
        // Removing all unnecessary digits 
        for (int j = 0; j < size; j++)
        { 
            if (test.charAt(j) == x + 48 || test.charAt(j) == y + 48) 
            { 
                newtest += test.charAt(j); 
            } 
        } 
  
        if (newtest.length() > 0) { 
            int size1 = newtest.length(); 
  
            // Prefix Sum Array for X+1 digit 
            int []prefix = new int[size1]; 
            for (int j = 0; j < size1; j++)
            { 
                prefix[j] = 0;
                if (newtest.charAt(j) == y + 48) 
                { 
                    prefix[j]++; 
                } 
            } 
  
            for (int j = 1; j < size1; j++)
            { 
                prefix[j] += prefix[j - 1]; 
            } 
  
            int count = 0; 
            int firstcount = 0; 
  
            // Sum of squares 
            int ss = 0; 
  
            // Previous sum of all possible pairs 
            int prev = 0; 
  
            for (int j = 0; j < size1; j++) 
            { 
                if (newtest.charAt(j) == x + 48) 
                { 
                    count++; 
                    firstcount++; 
                } 
                else 
                { 
  
                    ss += count * count; 
  
                    // To find sum of multiplication of all 
                    // possible pairs 
                    int pairsum = (firstcount * firstcount - ss) / 2; 
                    int temp = pairsum; 
  
                    // To prevent overcounting 
                    pairsum -= prev; 
                    prev = temp; 
  
                    int secondway = prefix[size1 - 1]; 
                    if (j != 0) 
                        secondway -= prefix[j - 1]; 
  
                    int answer = count * (count - 1) 
                                * secondway * (secondway - 1); 
                    answer /= 4; 
                    answer += (pairsum * secondway 
                            * (secondway - 1)) / 2; 
  
                    // Adding ways for all possible x 
                    total += answer; 
                    count = 0; 
                } 
            } 
        } 
    } 
  
    return total; 
} 
  
// Driver code 
public static void main (String[] args) 
{ 
    String test = "13134422"; 
    int MOD = 1000000007;
    System.out.println(solve(test,MOD));
  
} 
} 
  
// This code is contributed by krikti..


Python3
# Python3 implementation of the approach
  
MOD= 1000000007
  
# Function to return the total
# requried sub-sequences
def solve(test):
  
    size = len(test)
    total = 0
  
    # Find ways for all values of x
    for i in range(9):
        x = i
  
        # x+1
        y = i + 1
        newtest=""
  
        # Removing all unnecessary digits
        for j in range(size):
            if (ord(test[j]) == x + 48 or ord(test[j]) == y + 48):
                newtest += test[j]
  
  
        if (len(newtest) > 0):
            size1 = len(newtest)
  
            # Prefix Sum Array for X+1 digit
            prefix=[0 for i in range(size1)]
  
            for j in range(size1):
                if (ord(newtest[j]) == y + 48):
                    prefix[j]+=1
  
            for j in range(1,size1):
                prefix[j] += prefix[j - 1]
  
            count = 0
            firstcount = 0
  
            # Sum of squares
            ss = 0
  
            # Previous sum of all possible pairs
            prev = 0
  
            for j in range(size1):
                if (ord(newtest[j]) == x + 48):
                    count+=1
                    firstcount+=1
  
                else:
  
                    ss += count * count
  
                    # To find sum of multiplication of all
                    # possible pairs
                    pairsum = (firstcount * firstcount - ss) // 2
                    temp = pairsum
  
                    # To prevent overcounting
                    pairsum -= prev
                    prev = temp
  
                    secondway = prefix[size1 - 1]
                    if (j != 0):
                        secondway -= prefix[j - 1]
  
                    answer = count * (count - 1)* secondway * (secondway - 1)
                    answer //= 4
                    answer += (pairsum * secondway * (secondway - 1)) // 2
  
                    # Adding ways for all possible x
                    total += answer
                    count = 0
  
    return total
  
# Driver code
test = "13134422"
print(solve(test))
  
# This code is contributed by mohit kumar 29


C#
// C# Implementation of above approach 
  
using System;
  
class GFG 
{ 
  
    // Function to return the total 
    // requried sub-sequences 
    static int solve(string test, int MOD) 
    { 
        int size = test.Length; 
        int total = 0; 
      
        // Find ways for all values of x 
        for (int i = 0; i <= 8; i++) 
        { 
            int x = i; 
      
            // x+1 
            int y = i + 1; 
            string newtest = ""; 
      
            // Removing all unnecessary digits 
            for (int j = 0; j < size; j++) 
            { 
                if (test[j] == x + 48 || test[j] == y + 48) 
                { 
                    newtest += test[j]; 
                } 
            } 
      
            if (newtest.Length > 0) { 
                int size1 = newtest.Length; 
      
                // Prefix Sum Array for X+1 digit 
                int []prefix = new int[size1]; 
                for (int j = 0; j < size1; j++) 
                { 
                    prefix[j] = 0; 
                    if (newtest[j] == y + 48) 
                    { 
                        prefix[j]++; 
                    } 
                } 
      
                for (int j = 1; j < size1; j++) 
                { 
                    prefix[j] += prefix[j - 1]; 
                } 
      
                int count = 0; 
                int firstcount = 0; 
      
                // Sum of squares 
                int ss = 0; 
      
                // Previous sum of all possible pairs 
                int prev = 0; 
      
                for (int j = 0; j < size1; j++) 
                { 
                    if (newtest[j] == x + 48) 
                    { 
                        count++; 
                        firstcount++; 
                    } 
                    else
                    { 
      
                        ss += count * count; 
      
                        // To find sum of multiplication of all 
                        // possible pairs 
                        int pairsum = (firstcount * firstcount - ss) / 2; 
                        int temp = pairsum; 
      
                        // To prevent overcounting 
                        pairsum -= prev; 
                        prev = temp; 
      
                        int secondway = prefix[size1 - 1]; 
                        if (j != 0) 
                            secondway -= prefix[j - 1]; 
      
                        int answer = count * (count - 1) 
                                    * secondway * (secondway - 1); 
                        answer /= 4; 
                        answer += (pairsum * secondway 
                                * (secondway - 1)) / 2; 
      
                        // Adding ways for all possible x 
                        total += answer; 
                        count = 0; 
                    } 
                } 
            } 
        } 
      
        return total; 
    } 
      
    // Driver code 
    public static void Main () 
    { 
        string test = "13134422"; 
        int MOD = 1000000007; 
        Console.WriteLine(solve(test,MOD)); 
      
    } 
} 
  
// This code is contributed by AnkitRai01


输出:
2