📌  相关文章
📜  给定大量数字,请检查数字的子序列是否可被8整除

📅  最后修改于: 2021-04-29 13:56:39             🧑  作者: Mango

给定最多100个数字。在删除某些数字后,我们必须检查是否有可能获得至少一个可以被8整除的数字。我们禁止重新排列这些数字。

例子 :

Input : 1787075866
Output : Yes
There exist more one or more subsequences
divisible by 8. Example subsequences are
176, 16 and 8.

Input : 6673177113
Output : No 
No subsequence is divisible by 8.

Input : 3144
Output : Yes
The subsequence 344 is divisible by 8.

可除以八的性质:当且仅当其后三位数构成可被八除的数字时,才可将其除以八。因此,仅测试通过划掉即可从原始号码获得的且最多包含三个数字的号码就足够了,即,我们检查所有一位,两位和三位数字的组合。

方法1(蛮力):
我们采用蛮力方法。我们使用迭代阶梯置换所有可能的一位数字,两位数字和三位数字组合。如果遇到一位数被8整除或两位数被8整除或三位数被8整除的组合,那么这将是我们解决问题的方法。

C++
// C++ program to check if a subsequence of digits
// is divisible by 8.
#include 
using namespace std;
 
// Function to calculate any permutation divisible
// by 8. If such permutation exists, the function
// will return that permutation else it will return -1
bool isSubSeqDivisible(string str)
{
    // Converting string to integer array for ease
    // of computations (Indexing in arr[] is
    // considered to be starting from 1)
    int l = str.length();
    int arr[l];
    for (int i = 0; i < l; i++)
        arr[i] = str[i] - '0';
 
    // Generating all possible permutations and checking
    // if any such permutation is divisible by 8
    for (int i = 0; i < l; i++) {
        for (int j = i; j < l; j++) {
            for (int k = j; k < l; k++) {
                if (arr[i] % 8 == 0)
                    return true;
 
                else if ((arr[i] * 10 + arr[j]) % 8 == 0 && i != j)
                    return true;
 
                else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0 && i != j && j != k && i != k)
                    return true;
            }
        }
    }
    return false;
}
 
// Driver function
int main()
{
    string str = "3144";
    if (isSubSeqDivisible(str))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}


Java
// Java program to check if a subsequence
// of digits is divisible by 8.
import java.io.*;
 
class GFG {
 
    // Function to calculate any permutation
    // divisible by 8. If such permutation
    // exists, the function will return
    // that permutation else it will return -1
    static boolean isSubSeqDivisible(String str)
    {
 
        int i, j, k, l = str.length();
        int arr[] = new int[l];
 
        // Converting string to integer array for ease
        // of computations (Indexing in arr[] is
        // considered to be starting from 1)
        for (i = 0; i < l; i++)
            arr[i] = str.charAt(i) - '0';
 
        // Generating all possible permutations
        // and checking if any such
        // permutation is divisible by 8
        for (i = 0; i < l; i++) {
            for (j = i; j < l; j++) {
                for (k = j; k < l; k++) {
                    if (arr[i] % 8 == 0)
                        return true;
 
                    else if ((arr[i] * 10 + arr[j]) % 8 == 0 && i != j)
                        return true;
 
                    else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0
                             && i != j && j != k && i != k)
                        return true;
                }
            }
        }
        return false;
    }
 
    // Driver function
    public static void main(String args[])
    {
 
        String str = "3144";
        if (isSubSeqDivisible(str))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
 
// This code is contributed by Nikita Tiwari.


Python3
# Python3 program to
# check if a subsequence of digits
# is divisible by 8.
 
# Function to calculate any
# permutation divisible
# by 8. If such permutation
# exists, the function
# will return that permutation
# else it will return -1
def isSubSeqDivisible(st) :
 
    l = len(st)
    arr = [int(ch) for ch in st]
 
    # Generating all possible
    # permutations and checking
    # if any such permutation
    # is divisible by 8
    for i in range(0, l) :
        for j in range(i, l) :
            for k in range(j, l) :
                if (arr[i] % 8 == 0) :
                    return True
  
                elif ((arr[i]*10 + arr[j])% 8 == 0 and i != j) :
                    return True
  
                elif ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0 and i != j and j != k and i != k) :
                    return True
            
    return False
  
# Driver function
 
st = "3144"
if (isSubSeqDivisible(st)) :
    print("Yes")
else :
    print("No")
 
# This code is contributed
# by Nikita Tiwari.


C#
// C# program to check if a subsequence
// of digits is divisible by 8.
using System;
 
class GFG {
 
    // Function to calculate any permutation
    // divisible by 8. If such permutation
    // exists, the function will return
    // that permutation else it will return -1
    static bool isSubSeqDivisible(string str)
    {
        int i, j, k, l = str.Length;
        int[] arr = new int[l];
 
        // Converting string to integer array for ease
        // of computations (Indexing in arr[] is
        // considered to be starting from 1)
        for (i = 0; i < n; i++)
           arr[i] = str[i] - '0';
 
        // Generating all possible permutations
        // and checking if any such
        // permutation is divisible by 8
        for (i = 0; i < l; i++) {
            for (j = i; j < l; j++) {
                for (k = j; k < l; k++) {
                    if (arr[i] % 8 == 0)
                        return true;
 
                    else if ((arr[i] * 10 + arr[j])
                                     % 8
                                 == 0
                             && i != j)
                        return true;
 
                    else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0
                             && i != j && j != k
                             && i != k)
                        return true;
                }
            }
        }
 
        return false;
    }
 
    // Driver function
    public static void Main()
    {
        string str = "3144";
 
        if (isSubSeqDivisible(str))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
 
// This code is contributed by vt_m.


Javascript


C++
// C++ program to find if there is a subsequence
// of digits divisible by 8.
#include 
using namespace std;
 
// Function takes in an array of numbers,
// dynamically goes on the location and
// makes combination of numbers.
bool isSubSeqDivisible(string str)
{
    int n = str.length();
    int dp[n + 1][10];
    memset(dp, 0, sizeof(dp));
 
    // Converting string to integer array for ease
    // of computations (Indexing in arr[] is
    // considered to be starting from 1)
    int arr[n + 1];
    for (int i = 1; i <= n; i++)
        arr[i] = str[i - 1] - '0';
 
    for (int i = 1; i <= n; i++) {
 
        dp[i][arr[i] % 8] = 1;
        for (int j = 0; j < 8; j++) {
 
            // If we consider the number in our combination,
            // we add it to the previous combination
            if (dp[i - 1][j] > dp[i][(j * 10 + arr[i]) % 8])
                dp[i][(j * 10 + arr[i]) % 8] = dp[i - 1][j];
 
            // If we exclude the number from our combination
            if (dp[i - 1][j] > dp[i][j])
                dp[i][j] = dp[i - 1][j];
        }
    }
 
    for (int i = 1; i <= n; i++) {
 
        // If at dp[i][0], we find value 1/true, it shows
        // that the number exists at the value of 'i'
        if (dp[i][0] == 1)
            return true;
    }
 
    return false;
}
 
// Driver function
int main()
{
    string str = "3144";
    if (isSubSeqDivisible(str))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}


Java
// Java program to find if there is a
// subsequence of digits divisible by 8.
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.
    static boolean isSubSeqDivisible(String str)
    {
 
        int n = str.length();
        int dp[][] = new int[n + 1][10];
 
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int arr[] = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str.charAt(i - 1) - '0');
 
        for (int i = 1; i <= n; i++) {
 
            dp[i][arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
 
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1][j] > dp[i][(j * 10
                                          + arr[i])
                                         % 8])
                    dp[i][(j * 10 + arr[i]) % 8]
                        = dp[i - 1][j];
 
                // If we exclude the number from
                // our combination
                if (dp[i - 1][j] > dp[i][j])
                    dp[i][j] = dp[i - 1][j];
            }
        }
 
        for (int i = 1; i <= n; i++) {
 
            // If at dp[i][0], we find value 1/true,
            // it shows that the number exists at
            // the value of 'i'
            if (dp[i][0] == 1)
                return true;
        }
 
        return false;
    }
 
    // Driver function
    public static void main(String args[])
    {
        String str = "3144";
        if (isSubSeqDivisible(str))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
 
/* This code is contributed by Nikita Tiwari.*/


Python3
# Python3 program to find
# if there is a subsequence
# of digits divisible by 8.
 
# Function takes in an array of numbers,
# dynamically goes on the location and
# makes combination of numbers.
def isSubSeqDivisible(str):
    n = len(str)
    dp = [[0 for i in range(10)]
             for i in range(n + 1)]
              
    # Converting string to integer
    # array for ease of computations
    # (Indexing in arr[] is considered
    # to be starting from 1)
    arr = [0 for i in range(n + 1)]
    for i in range(1, n + 1):
        arr[i] = int(str[i - 1]);
 
    for i in range(1, n + 1):
        dp[i][arr[i] % 8] = 1;
        for j in range(8):
             
            # If we consider the number
            # in our combination, we add
            # it to the previous combination
            if (dp[i - 1][j] > dp[i][(j * 10 + arr[i]) % 8]):
                dp[i][(j * 10 + arr[i]) % 8] = dp[i - 1][j]
                 
            # If we exclude the number
            # from our combination
            if (dp[i - 1][j] > dp[i][j]):
                dp[i][j] = dp[i - 1][j]
 
    for i in range(1, n + 1):
         
        # If at dp[i][0], we find
        # value 1/true, it shows
        # that the number exists
        # at the value of 'i'
        if (dp[i][0] == 1):
            return True
    return False
 
# Driver Code
str = "3144"
if (isSubSeqDivisible(str)):
    print("Yes")
else:
    print("No")
     
# This code is contributed
# by sahilshelangia


C#
// C# program to find if there is a
// subsequence of digits divisible by 8.
using System;
 
class GFG {
 
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.
    static bool isSubSeqDivisible(String str)
    {
 
        int n = str.Length;
        int[, ] dp = new int[n + 1, 10];
 
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str[i - 1] - '0');
 
        for (int i = 1; i <= n; i++) {
            dp[i, arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
 
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1, j] > dp[i, (j * 10
                                          + arr[i])
                                             % 8])
                    dp[i, (j * 10 + arr[i]) % 8]
                        = dp[i - 1, j];
 
                // If we exclude the number from
                // our combination
                if (dp[i - 1, j] > dp[i, j])
                    dp[i, j] = dp[i - 1, j];
            }
        }
 
        for (int i = 1; i <= n; i++) {
 
            // If at dp[i][0], we find value
            // 1/true, it shows that the number
            // exists at the value of 'i'
            if (dp[i, 0] == 1)
                return true;
        }
 
        return false;
    }
 
    // Driver function
    public static void Main()
    {
        string str = "3144";
 
        if (isSubSeqDivisible(str))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
 
// This code is contributed by vt_m.


PHP
 $dp[$i][($j * 10 +
                                           $arr[$i]) % 8])
                $dp[$i][($j * 10 +
                         $arr[$i]) % 8] = $dp[$i - 1][$j];
 
            // If we exclude the number
            // from our combination
            if ($dp[$i - 1][$j] > $dp[$i][$j])
                $dp[$i][$j] = $dp[$i - 1][$j];
        }
    }
 
    for ($i = 1; $i <= $n; $i++)
    {
 
        // If at dp[i][0], we find value 1/true,
        // it shows that the number exists at
        // the value of 'i'
        if ($dp[$i][0] == 1)
            return true;
    }
 
    return false;
}
 
// Driver Code
$str = "3144";
if (isSubSeqDivisible($str))
    echo "Yes";
else
    echo "No";
 
// This code is contributed
// by ChitraNayal
?>


C++
// C++ program to check if given string
// has a subsequence divisible by 8
#include
using namespace std;
// Driver function
int main(){
     
    string str = "129365";
     
    // map key will be tens place digit of number
        // that is divisible by 8 and value will
        // be units place digit
    map mp;
     
    // For filling the map let start
        // with initial value 8
    int no = 8;
     
    while(no < 100){
        no = no + 8;
     
        // key is digit at tens place and value is
            // digit at units place mp.insert({key, value})
        mp.insert({(no / 10) % 10, no % 10});
    }
     
    // Create a hash to check if we visited a number
    vector visited(10, false);
     
    int i;
    // Iterate from last index to 0th index
    for(i = str.length() - 1; i >= 0; i--){
         
        // If 8 is present in string then
            // 8 divided 8 hence print yes
        if(str[i] == '8')
           {
               cout << "Yes";
                break;
           }
         
        // considering present character as the second
        // digit of two digits no we check if the value
        // of this key is marked in hash or not
        // If marked then we a have a number divisible by 8
        if(visited[mp[str[i] - '0']]){
            cout << "Yes";
            break;
        }
        visited[str[i] - '0'] = true;     
         
    }
    // If no subsequence divisible by 8 
    if(i == -1)
        cout << "No";
    return 0;
}


Java
// Java program to check if
// given String has a subsequence
// divisible by 8
import java.util.*;
class GFG{
   
// Driver code
public static void main(String[] args)
{
  String str = "129365";
 
  // map key will be tens place
  // digit of number that is
  // divisible by 8 and value will
  // be units place digit
  HashMap mp = new HashMap();
 
  // For filling the map let start
  // with initial value 8
  int no = 8;
 
  while(no < 100)
  {
    no = no + 8;
 
    // key is digit at tens place
    // and value is digit at units
    // place mp.add({key, value})
    //if(mp.containsKey((no / 10) % 10))
    mp.put((no / 10) % 10, no % 10);
  }
 
  // Create a hash to check if
  // we visited a number
  boolean[] visited = new boolean[10];
 
  int i;
   
  // Iterate from last index
  // to 0th index
  for(i = str.length() - 1;
      i >= 0; i--)
  {
    // If 8 is present in String then
    // 8 divided 8 hence print yes
    if(str.charAt(i) == '8')
    {
      System.out.print("Yes");
      break;
    }
 
    // considering present character
    // as the second digit of two
    // digits no we check if the value
    // of this key is marked in hash or not
    // If marked then we a have a number
    // divisible by 8
    if(visited[mp.get(str.charAt(i)- '0')])
    {
      System.out.print("Yes");
      break;
    }
    visited[str.charAt(i) - '0'] = true;    
 
  }
  // If no subsequence divisible
  // by 8
  if(i == -1)
    System.out.print("No");
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python3 program to check if given string
# has a subsequence divisible by 8
Str = "129365"
 
# map key will be tens place digit of number
# that is divisible by 8 and value will
# be units place digit
mp = {}
 
# For filling the map let start
# with initial value 8
no = 8
 
while(no < 100) :
    no = no + 8
 
    # key is digit at tens place and value is
    # digit at units place mp.insert({key, value})
    mp[(no // 10) % 10] = no % 10
 
# Create a hash to check if we visited a number
visited = [False] * 10
 
# Iterate from last index to 0th index
for i in range(len(Str) - 1, -1, -1) :
     
    # If 8 is present in string then
    # 8 divided 8 hence print yes
    if(Str[i] == '8') :
     
        print("Yes", end = "")
        break
     
    # considering present character as the second
    # digit of two digits no we check if the value
    # of this key is marked in hash or not
    # If marked then we a have a number divisible by 8
    if visited[mp[ord(Str[i]) - ord('0')]] :
        print("Yes", end = "")
        break
 
    visited[ord(Str[i]) - ord('0')] = True
 
# If no subsequence divisible by 8
if(i == -1) :
    print("No")
 
    # This code is contributed by divyeshrabadiya07


C#
// C# program to check if given
// String has a subsequence
// divisible by 8
using System;
using System.Collections.Generic;
 
class GFG{
 
// Driver code
public static void Main(String[] args)
{
    String str = "129365";
     
    // Map key will be tens place
    // digit of number that is
    // divisible by 8 and value will
    // be units place digit
    Dictionary mp = new Dictionary();
 
    // For filling the map let start
    // with initial value 8
    int no = 8;
 
    while (no < 100)
    {
        no = no + 8;
         
        // Key is digit at tens place
        // and value is digit at units
        // place mp.Add({key, value})
        if (mp.ContainsKey((no / 10) % 10))
            mp[(no / 10) % 10] = no % 10;
        else
            mp.Add((no / 10) % 10, no % 10);
    }
 
    // Create a hash to check if
    // we visited a number
    bool[] visited = new bool[10];
 
    int i;
 
    // Iterate from last index
    // to 0th index
    for(i = str.Length - 1; i >= 0; i--)
    {
         
        // If 8 is present in String then
        // 8 divided 8 hence print yes
        if (str[i] == '8')
        {
            Console.Write("Yes");
            break;
        }
 
        // Considering present character
        // as the second digit of two
        // digits no we check if the value
        // of this key is marked in hash or not
        // If marked then we a have a number
        // divisible by 8
        if (visited[mp[str[i] - '0']])
        {
            Console.Write("Yes");
            break;
        }
        visited[str[i] - '0'] = true;
    }
     
    // If no subsequence divisible
    // by 8
    if (i == -1)
        Console.Write("No");
}
}
 
// This code is contributed by Princi Singh


输出
Yes

方法2(动态编程):
尽管我们只有100位数字,但对于更长的数字,则我们的程序可能会超过给定的时间限制。
因此,我们通过使用动态编程方法来优化代码。

a_{i}

是样本的第i位。我们生成一个矩阵dp [i] [j],1 <= i <= n和0 <= j <8。如果我们可以从长度i的前缀中删除一些数字,使得剩余的数字为j模8,则dp的值为true,否则为false。为了广泛理解该概念,如果在索引处,我们找到该索引的模8元素,则将

dp[i][a_{i}mod8] = 1

对于所有其他数字,我们建立在一个简单的概念上,即该数字的加法将有助于形成一个可被8整除的数字,或者应将其排除在外。

注意:我们还必须记住,我们无法更改订单
现在,

dp[i][(j*10+a_{i}) mod 8]=max(dp[i][(j*10+a_{i}) mod 8], dp[i-1][j])

如果我们将当前数字添加到上一个结果。

dp[i][(j*10) mod 8]=max(dp[i][(j*10) mod 8], dp[i-1][j])

如果我们在编队中排除当前数字。
现在,如果存在这样的数字,则对于dp [i] [0]中的任何i ,我们都将获得“ true”

C++

// C++ program to find if there is a subsequence
// of digits divisible by 8.
#include 
using namespace std;
 
// Function takes in an array of numbers,
// dynamically goes on the location and
// makes combination of numbers.
bool isSubSeqDivisible(string str)
{
    int n = str.length();
    int dp[n + 1][10];
    memset(dp, 0, sizeof(dp));
 
    // Converting string to integer array for ease
    // of computations (Indexing in arr[] is
    // considered to be starting from 1)
    int arr[n + 1];
    for (int i = 1; i <= n; i++)
        arr[i] = str[i - 1] - '0';
 
    for (int i = 1; i <= n; i++) {
 
        dp[i][arr[i] % 8] = 1;
        for (int j = 0; j < 8; j++) {
 
            // If we consider the number in our combination,
            // we add it to the previous combination
            if (dp[i - 1][j] > dp[i][(j * 10 + arr[i]) % 8])
                dp[i][(j * 10 + arr[i]) % 8] = dp[i - 1][j];
 
            // If we exclude the number from our combination
            if (dp[i - 1][j] > dp[i][j])
                dp[i][j] = dp[i - 1][j];
        }
    }
 
    for (int i = 1; i <= n; i++) {
 
        // If at dp[i][0], we find value 1/true, it shows
        // that the number exists at the value of 'i'
        if (dp[i][0] == 1)
            return true;
    }
 
    return false;
}
 
// Driver function
int main()
{
    string str = "3144";
    if (isSubSeqDivisible(str))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}

Java

// Java program to find if there is a
// subsequence of digits divisible by 8.
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.
    static boolean isSubSeqDivisible(String str)
    {
 
        int n = str.length();
        int dp[][] = new int[n + 1][10];
 
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int arr[] = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str.charAt(i - 1) - '0');
 
        for (int i = 1; i <= n; i++) {
 
            dp[i][arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
 
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1][j] > dp[i][(j * 10
                                          + arr[i])
                                         % 8])
                    dp[i][(j * 10 + arr[i]) % 8]
                        = dp[i - 1][j];
 
                // If we exclude the number from
                // our combination
                if (dp[i - 1][j] > dp[i][j])
                    dp[i][j] = dp[i - 1][j];
            }
        }
 
        for (int i = 1; i <= n; i++) {
 
            // If at dp[i][0], we find value 1/true,
            // it shows that the number exists at
            // the value of 'i'
            if (dp[i][0] == 1)
                return true;
        }
 
        return false;
    }
 
    // Driver function
    public static void main(String args[])
    {
        String str = "3144";
        if (isSubSeqDivisible(str))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
 
/* This code is contributed by Nikita Tiwari.*/

Python3

# Python3 program to find
# if there is a subsequence
# of digits divisible by 8.
 
# Function takes in an array of numbers,
# dynamically goes on the location and
# makes combination of numbers.
def isSubSeqDivisible(str):
    n = len(str)
    dp = [[0 for i in range(10)]
             for i in range(n + 1)]
              
    # Converting string to integer
    # array for ease of computations
    # (Indexing in arr[] is considered
    # to be starting from 1)
    arr = [0 for i in range(n + 1)]
    for i in range(1, n + 1):
        arr[i] = int(str[i - 1]);
 
    for i in range(1, n + 1):
        dp[i][arr[i] % 8] = 1;
        for j in range(8):
             
            # If we consider the number
            # in our combination, we add
            # it to the previous combination
            if (dp[i - 1][j] > dp[i][(j * 10 + arr[i]) % 8]):
                dp[i][(j * 10 + arr[i]) % 8] = dp[i - 1][j]
                 
            # If we exclude the number
            # from our combination
            if (dp[i - 1][j] > dp[i][j]):
                dp[i][j] = dp[i - 1][j]
 
    for i in range(1, n + 1):
         
        # If at dp[i][0], we find
        # value 1/true, it shows
        # that the number exists
        # at the value of 'i'
        if (dp[i][0] == 1):
            return True
    return False
 
# Driver Code
str = "3144"
if (isSubSeqDivisible(str)):
    print("Yes")
else:
    print("No")
     
# This code is contributed
# by sahilshelangia

C#

// C# program to find if there is a
// subsequence of digits divisible by 8.
using System;
 
class GFG {
 
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.
    static bool isSubSeqDivisible(String str)
    {
 
        int n = str.Length;
        int[, ] dp = new int[n + 1, 10];
 
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str[i - 1] - '0');
 
        for (int i = 1; i <= n; i++) {
            dp[i, arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
 
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1, j] > dp[i, (j * 10
                                          + arr[i])
                                             % 8])
                    dp[i, (j * 10 + arr[i]) % 8]
                        = dp[i - 1, j];
 
                // If we exclude the number from
                // our combination
                if (dp[i - 1, j] > dp[i, j])
                    dp[i, j] = dp[i - 1, j];
            }
        }
 
        for (int i = 1; i <= n; i++) {
 
            // If at dp[i][0], we find value
            // 1/true, it shows that the number
            // exists at the value of 'i'
            if (dp[i, 0] == 1)
                return true;
        }
 
        return false;
    }
 
    // Driver function
    public static void Main()
    {
        string str = "3144";
 
        if (isSubSeqDivisible(str))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
 
// This code is contributed by vt_m.

的PHP

 $dp[$i][($j * 10 +
                                           $arr[$i]) % 8])
                $dp[$i][($j * 10 +
                         $arr[$i]) % 8] = $dp[$i - 1][$j];
 
            // If we exclude the number
            // from our combination
            if ($dp[$i - 1][$j] > $dp[$i][$j])
                $dp[$i][$j] = $dp[$i - 1][$j];
        }
    }
 
    for ($i = 1; $i <= $n; $i++)
    {
 
        // If at dp[i][0], we find value 1/true,
        // it shows that the number exists at
        // the value of 'i'
        if ($dp[$i][0] == 1)
            return true;
    }
 
    return false;
}
 
// Driver Code
$str = "3144";
if (isSubSeqDivisible($str))
    echo "Yes";
else
    echo "No";
 
// This code is contributed
// by ChitraNayal
?>
输出
Yes

使用动态方法,我们的时间复杂度降低到O(8 * n),其中8是可分割的数字,n是我们输入的长度。因此,总体复杂度为O(n)。

方法3
对于这个问题,我们只需要检查是否存在一个可被8整除的两位数子序列(8的可除性检验)
我们首先找到所有可以被8整除的2位数字,并将十位数字与单位位数字进行映射
即:-16,24,32,40,48,56,64,72,80,88,96
忽略48,因为8总是可以被8整除,类似地80和88中也有8使得这些子序列总是可以被8整除。
因此,我们使用map即stl map在C++中映射1到6、2到4、3到2,依此类推。
构建完地图后,我们从最后一个索引开始遍历字符串,并检查是否访问了当前索引号的映射值,因此我们需要一个访问数组,如果访问了该索引,它将存储true,否则返回false
例如:-3769
最后一个索引的第一个字符是9,因此我们检查是否访问了6(即96是否为子序列),我们在访问数组中标记了9
下一个字符是6,所以我们检查是否有4个访问(即64),在访问数组中标记6
下一个字符是7,所以我们检查是否访问了2(即72),在访问数组中标记了7
下一个字符是3,因此我们检查是否访问了6(即36),是标记为6,因此我们打印是。

C++

// C++ program to check if given string
// has a subsequence divisible by 8
#include
using namespace std;
// Driver function
int main(){
     
    string str = "129365";
     
    // map key will be tens place digit of number
        // that is divisible by 8 and value will
        // be units place digit
    map mp;
     
    // For filling the map let start
        // with initial value 8
    int no = 8;
     
    while(no < 100){
        no = no + 8;
     
        // key is digit at tens place and value is
            // digit at units place mp.insert({key, value})
        mp.insert({(no / 10) % 10, no % 10});
    }
     
    // Create a hash to check if we visited a number
    vector visited(10, false);
     
    int i;
    // Iterate from last index to 0th index
    for(i = str.length() - 1; i >= 0; i--){
         
        // If 8 is present in string then
            // 8 divided 8 hence print yes
        if(str[i] == '8')
           {
               cout << "Yes";
                break;
           }
         
        // considering present character as the second
        // digit of two digits no we check if the value
        // of this key is marked in hash or not
        // If marked then we a have a number divisible by 8
        if(visited[mp[str[i] - '0']]){
            cout << "Yes";
            break;
        }
        visited[str[i] - '0'] = true;     
         
    }
    // If no subsequence divisible by 8 
    if(i == -1)
        cout << "No";
    return 0;
}

Java

// Java program to check if
// given String has a subsequence
// divisible by 8
import java.util.*;
class GFG{
   
// Driver code
public static void main(String[] args)
{
  String str = "129365";
 
  // map key will be tens place
  // digit of number that is
  // divisible by 8 and value will
  // be units place digit
  HashMap mp = new HashMap();
 
  // For filling the map let start
  // with initial value 8
  int no = 8;
 
  while(no < 100)
  {
    no = no + 8;
 
    // key is digit at tens place
    // and value is digit at units
    // place mp.add({key, value})
    //if(mp.containsKey((no / 10) % 10))
    mp.put((no / 10) % 10, no % 10);
  }
 
  // Create a hash to check if
  // we visited a number
  boolean[] visited = new boolean[10];
 
  int i;
   
  // Iterate from last index
  // to 0th index
  for(i = str.length() - 1;
      i >= 0; i--)
  {
    // If 8 is present in String then
    // 8 divided 8 hence print yes
    if(str.charAt(i) == '8')
    {
      System.out.print("Yes");
      break;
    }
 
    // considering present character
    // as the second digit of two
    // digits no we check if the value
    // of this key is marked in hash or not
    // If marked then we a have a number
    // divisible by 8
    if(visited[mp.get(str.charAt(i)- '0')])
    {
      System.out.print("Yes");
      break;
    }
    visited[str.charAt(i) - '0'] = true;    
 
  }
  // If no subsequence divisible
  // by 8
  if(i == -1)
    System.out.print("No");
}
}
 
// This code is contributed by shikhasingrajput

Python3

# Python3 program to check if given string
# has a subsequence divisible by 8
Str = "129365"
 
# map key will be tens place digit of number
# that is divisible by 8 and value will
# be units place digit
mp = {}
 
# For filling the map let start
# with initial value 8
no = 8
 
while(no < 100) :
    no = no + 8
 
    # key is digit at tens place and value is
    # digit at units place mp.insert({key, value})
    mp[(no // 10) % 10] = no % 10
 
# Create a hash to check if we visited a number
visited = [False] * 10
 
# Iterate from last index to 0th index
for i in range(len(Str) - 1, -1, -1) :
     
    # If 8 is present in string then
    # 8 divided 8 hence print yes
    if(Str[i] == '8') :
     
        print("Yes", end = "")
        break
     
    # considering present character as the second
    # digit of two digits no we check if the value
    # of this key is marked in hash or not
    # If marked then we a have a number divisible by 8
    if visited[mp[ord(Str[i]) - ord('0')]] :
        print("Yes", end = "")
        break
 
    visited[ord(Str[i]) - ord('0')] = True
 
# If no subsequence divisible by 8
if(i == -1) :
    print("No")
 
    # This code is contributed by divyeshrabadiya07

C#

// C# program to check if given
// String has a subsequence
// divisible by 8
using System;
using System.Collections.Generic;
 
class GFG{
 
// Driver code
public static void Main(String[] args)
{
    String str = "129365";
     
    // Map key will be tens place
    // digit of number that is
    // divisible by 8 and value will
    // be units place digit
    Dictionary mp = new Dictionary();
 
    // For filling the map let start
    // with initial value 8
    int no = 8;
 
    while (no < 100)
    {
        no = no + 8;
         
        // Key is digit at tens place
        // and value is digit at units
        // place mp.Add({key, value})
        if (mp.ContainsKey((no / 10) % 10))
            mp[(no / 10) % 10] = no % 10;
        else
            mp.Add((no / 10) % 10, no % 10);
    }
 
    // Create a hash to check if
    // we visited a number
    bool[] visited = new bool[10];
 
    int i;
 
    // Iterate from last index
    // to 0th index
    for(i = str.Length - 1; i >= 0; i--)
    {
         
        // If 8 is present in String then
        // 8 divided 8 hence print yes
        if (str[i] == '8')
        {
            Console.Write("Yes");
            break;
        }
 
        // Considering present character
        // as the second digit of two
        // digits no we check if the value
        // of this key is marked in hash or not
        // If marked then we a have a number
        // divisible by 8
        if (visited[mp[str[i] - '0']])
        {
            Console.Write("Yes");
            break;
        }
        visited[str[i] - '0'] = true;
    }
     
    // If no subsequence divisible
    // by 8
    if (i == -1)
        Console.Write("No");
}
}
 
// This code is contributed by Princi Singh
输出
Yes

如果仔细观察,访问数组将始终具有10个字段,并且映射图将始终具有相同的大小,因此遍历字符串的空间复杂度将为O(1),时间复杂度将为O(n)。