Given string str of length N. The task is to find the number of integers obtained by replacing ‘?’ with any digit such that the formed integer gives remainder 5 when it is divided by 13.
Numbers can also begin with zero. The answer can be very large, so, output answer modulo 109 + 7.
Examples:
Input: str = “?44”
Output: 1
Only possible number is 044
Input: str = “7?4”
Output: 0
Input: str = “8?3?4233?4?”
Output: 770
Approach: Let dp[i][j] be the number of ways to create an i-digit number consistent with the first i digits of the given pattern and congruent to j modulo 13. As our base case, dp[0][i]=0 for i from 1 to 12, and dp[0][0]=1 (as our length-zero number has value zero and thus is zero mod 13.)
Notice that appending a digit k to the end of a number that’s j mod 13 gives a number that’s congruent to 10j+k mod 13. We use this fact to perform our transitions. For every state, dp[i][j] with i < N, iterate over the possible values of k. (If s[i]=’?’, there will be ten choices for k, and otherwise, there will only be one choice.) Then, we add dp[i][j] to dp[i+1][(10j+k)%13].
To get our final answer, we can simply print dp[N][5].
Below is the implementation of the above approach :
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;#define MOD (int)(1e9 + 7)// Function to find the count of integers// obtained by replacing '?' in a given// string such that formed integer// gives remainder 5 when it is divided by 13int modulo_13(string s, int n){ long long dp[n + 1][13] = { { 0 } }; // Initialise dp[0][0] = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < 10; j++) { int nxt = s[i] - '0'; // Place digit j at ? position if (s[i] == '?') nxt = j; // Get the remainder for (int k = 0; k < 13; k++) { int rem = (10 * k + nxt) % 13; dp[i + 1][rem] += dp[i][k]; dp[i + 1][rem] %= MOD; } if (s[i] != '?') break; } } // Return the required answer return (int)dp[n][5];}// Driver codeint main(){ string s = "?44"; int n = s.size(); cout << modulo_13(s, n); return 0;} |
Java
// Java implementation of the approachclass GFG {static int MOD = (int)(1e9 + 7);// Function to find the count of integers// obtained by replacing '?' in a given// string such that formed integer// gives remainder 5 when it is divided by 13static int modulo_13(String s, int n){ long [][]dp = new long[n + 1][13]; // Initialise dp[0][0] = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < 10; j++) { int nxt = s.charAt(i) - '0'; // Place digit j at ? position if (s.charAt(i) == '?') nxt = j; // Get the remainder for (int k = 0; k < 13; k++) { int rem = (10 * k + nxt) % 13; dp[i + 1][rem] += dp[i][k]; dp[i + 1][rem] %= MOD; } if (s.charAt(i) != '?') break; } } // Return the required answer return (int)dp[n][5];}// Driver codepublic static void main(String []args) { String s = "?44"; int n = s.length(); System.out.println(modulo_13(s, n));}}// This code is contributed by Rajput-Ji |
Python3
# Python3 implementation of the approach import numpy as npMOD = (int)(1e9 + 7) # Function to find the count of integers # obtained by replacing '?' in a given # string such that formed integer # gives remainder 5 when it is divided by 13 def modulo_13(s, n) : dp = np.zeros((n + 1, 13)); # Initialise dp[0][0] = 1; for i in range(n) : for j in range(10) : nxt = ord(s[i]) - ord('0'); # Place digit j at ? position if (s[i] == '?') : nxt = j; # Get the remainder for k in range(13) : rem = (10 * k + nxt) % 13; dp[i + 1][rem] += dp[i][k]; dp[i + 1][rem] %= MOD; if (s[i] != '?') : break; # Return the required answer return int(dp[n][5]); # Driver code if __name__ == "__main__" : s = "?44"; n = len(s); print(modulo_13(s, n)); # This code is contributed by AnkitRai01 |
C#
// C# implementation of the approachusing System; class GFG{static int MOD = (int)(1e9 + 7);// Function to find the count of integers// obtained by replacing '?' in a given// string such that formed integer// gives remainder 5 when it is divided by 13static int modulo_13(String s, int n){ long [,]dp = new long[n + 1, 13]; // Initialise dp[0, 0] = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < 10; j++) { int nxt = s[i] - '0'; // Place digit j at ? position if (s[i] == '?') nxt = j; // Get the remainder for (int k = 0; k < 13; k++) { int rem = (10 * k + nxt) % 13; dp[i + 1, rem] += dp[i, k]; dp[i + 1, rem] %= MOD; } if (s[i] != '?') break; } } // Return the required answer return (int)dp[n,5];}// Driver codepublic static void Main(String []args) { String s = "?44"; int n = s.Length; Console.WriteLine(modulo_13(s, n));}}// This code is contributed by 29AjayKumar |
Javascript
<script>// javascript implementation of the approach var MOD = parseInt(1e9 + 7); // Function to find the count of integers // obtained by replacing '?' in a given // string such that formed integer // gives remainder 5 when it is divided by 13 function modulo_13( s , n) { var dp = Array(n + 1).fill().map(()=>Array(13).fill(0)); // Initialise dp[0][0] = 1; for (i = 0; i < n; i++) { for (j = 0; j < 10; j++) { var nxt = s.charAt(i) - '0'; // Place digit j at ? position if (s.charAt(i) == '?') nxt = j; // Get the remainder for (k = 0; k < 13; k++) { var rem = (10 * k + nxt) % 13; dp[i + 1][rem] += dp[i][k]; dp[i + 1][rem] %= MOD; } if (s.charAt(i) != '?') break; } } // Return the required answer return parseInt( dp[n][5]); } // Driver code var s = "?44"; var n = s.length; document.write(modulo_13(s, n));// This code contributed by aashish1995</script> |
1
Time Complexity: O(100 * N)
Auxiliary Space: O(100 * N)
Efficient Approach : Space Optimization
In this approach we use a 1D array dp of length 13 instead a 2D matrix of length 100*N instead, which stores only the counts of remainders for the current position. This reduces the space complexity to O(13)
Implementation Steps:
- Initialize an array dp of length 13 to store the counts of remainders for the current position. Set dp[0] to 1.
- If the current character is ?, initialize an array nxt to indicate that all digits 0-9 are valid choices for the current position. Otherwise, set nxt to contain only the digit indicated by the current character.
- Initialize a new array dp_new to store the updated counts of remainders for the next position.
- For each remainder j in the current dp array, iterate over each valid digit k indicated by the nxt array.
- Compute the remainder obtained by appending digit k to the remainder j.
- Add the count of remainders for remainder j in the current dp array to the count of remainders for the new remainder rem in the dp_new array.
- Take the modulo of the sum.
- Copy the dp_new array into the dp array using the memcpy function.
- After iterating over all characters in the input string s, return the count of remainders for remainder 5 in the final dp array.
Implementation:
C++
// C++ program for above approach#include <bits/stdc++.h>using namespace std;#define MOD (int)(1e9 + 7)// Function to find the count of integers// obtained by replacing '?' in a given// string such that formed integer// gives remainder 5 when it is divided by 13int modulo_13(string s, int n){ // initialize DP with 0 int dp[13] = { 0 }; // Base Case dp[0] = 1; for (int i = 0; i < n; i++) { int nxt[10] = { 0 }; // Place digit j at ? position if (s[i] == '?') { for (int j = 0; j < 10; j++) nxt[j] = 1; } else { nxt[s[i] - '0'] = 1; } // iterate over subproblems to get the current // from previous computaton int dp_new[13] = { 0 }; for (int j = 0; j < 13; j++) { for (int k = 0; k < 10; k++) { if (!nxt[k]) continue; int rem = (10 * j + k) % 13; // Get the remainder dp_new[rem] += dp[j]; dp_new[rem] %= MOD; } } // assigning values for further iterations memcpy(dp, dp_new, sizeof(dp)); } // Return the required answer return dp[5];}// Driver Codeint main(){ string s = "?44"; int n = s.size(); // function call cout << modulo_13(s, n); return 0;} |
Java
import java.util.*;public class Main { static final int MOD = (int)(1e9 + 7); // Function to find the count of integers // obtained by replacing '?' in a given // string such that formed integer // gives remainder 5 when it is divided by 13 public static int modulo_13(String s, int n) { // initialize DP with 0 int[] dp = new int[13]; // Base Case dp[0] = 1; for (int i = 0; i < n; i++) { int[] nxt = new int[10]; // Place digit j at ? position if (s.charAt(i) == '?') { for (int j = 0; j < 10; j++) nxt[j] = 1; } else { nxt[s.charAt(i) - '0'] = 1; } // iterate over subproblems to get the current // from previous computaton int[] dp_new = new int[13]; for (int j = 0; j < 13; j++) { for (int k = 0; k < 10; k++) { if (nxt[k] == 0) continue; int rem = (10 * j + k) % 13; // Get the remainder dp_new[rem] += dp[j]; dp_new[rem] %= MOD; } } // assigning values for further iterations System.arraycopy(dp_new, 0, dp, 0, dp.length); } // Return the required answer return dp[5]; } // Driver Code public static void main(String[] args) { String s = "?44"; int n = s.length(); // function call System.out.println(modulo_13(s, n)); }} |
Python3
MOD = int(1e9 + 7)# Function to find the count of integers# obtained by replacing '?' in a given# string such that formed integer# gives remainder 5 when it is divided by 13def modulo_13(s): n = len(s) # initialize DP with 0 dp = [0] * 13 # Base Case dp[0] = 1 for i in range(n): nxt = [0] * 10 # Place digit j at ? position if s[i] == '?': nxt = [1] * 10 else: nxt[int(s[i])] = 1 # iterate over subproblems to get the current # from previous computaton dp_new = [0] * 13 for j in range(13): for k in range(10): if not nxt[k]: continue rem = (10 * j + k) % 13 # Get the remainder dp_new[rem] += dp[j] dp_new[rem] %= MOD # assigning values for further iterations dp = dp_new[:] # Return the required answer return dp[5]# Driver Codes = "?44"# function callprint(modulo_13(s)) |
Javascript
const MOD = 1e9 + 7;// Function to find the count of integers// obtained by replacing '?' in a given// string such that formed integer// gives remainder 5 when it is divided by 13function modulo_13(s, n) { // initialize DP with 0 let dp = new Array(13).fill(0); // Base Case dp[0] = 1; for (let i = 0; i < n; i++) { let nxt = new Array(10).fill(0); // Place digit j at ? position if (s[i] == '?') { for (let j = 0; j < 10; j++) nxt[j] = 1; } else { nxt[s[i] - '0'] = 1; } // iterate over subproblems to get the current // from previous computaton let dp_new = new Array(13).fill(0); for (let j = 0; j < 13; j++) { for (let k = 0; k < 10; k++) { if (!nxt[k]) continue; let rem = (10 * j + k) % 13; // Get the remainder dp_new[rem] += dp[j]; dp_new[rem] %= MOD; } } // assigning values for further iterations dp = [...dp_new]; } // Return the required answer return dp[5];}let s = "?44";let n = s.length;// function callconsole.log(modulo_13(s, n)); |
C#
// C# program for above approachusing System;public class Program { // Function to find the count of integers // obtained by replacing '?' in a given // string such that formed integer // gives remainder 5 when it is divided by 13 const int MOD = (int)(1e9 + 7); public static int Modulo13(string s, int n) { // initialize DP with 0 int[] dp = new int[13]; // Base Case dp[0] = 1; for (int i = 0; i < n; i++) { int[] nxt = new int[10]; // Place digit j at ? position if (s[i] == '?') { for (int j = 0; j < 10; j++) nxt[j] = 1; } else { nxt[s[i] - '0'] = 1; } // iterate over subproblems to get the current // from previous computaton int[] dp_new = new int[13]; for (int j = 0; j < 13; j++) { for (int k = 0; k < 10; k++) { if (nxt[k] == 0) continue; int rem = (10 * j + k) % 13; // Get the remainder dp_new[rem] += dp[j]; dp_new[rem] %= MOD; } } // assigning values for further iterations Array.Copy(dp_new, dp, dp_new.Length); } // Return the required answer return dp[5]; } // Driver Code public static void Main() { string s = "?44"; int n = s.Length; // function call Console.WriteLine(Modulo13(s, n)); }} |
Output
1
Time Complexity: O(N * 10 * 13) => O(N)
Auxiliary Space: O(13)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
