static void Main(string[] args) { ConsoleReader reader = new ConsoleReader(); /// Read test cases count reader.MoveNext(); int N = int.Parse(reader.Current); for (int j = 0; j < N; j++) { /// Read Max value reader.MoveNext(); int M = int.Parse(reader.Current); List <int> parsedNumbers = new List <int>(); reader.MoveNext(); string squished_status = reader.Current; /// Split squished_status into the smallest valid numbers /// Example: M = 5, squished_status = 141 => parsedNumbers = { 1, 4, 1 } /// Example: M = 12, squished_status = 101 => parsedNumbers = { 10, 1 } /// Example: M = 2, squished_status = 101 => Error int number = 0; foreach (char c in squished_status) { if (c == '0') { if (number == 0) { parsedNumbers.Clear(); break; } else { number *= 10; if (number > M) { number = 0; parsedNumbers.Clear(); break; } } } else { if (number != 0) { parsedNumbers.Add(number); } number = c - '0'; } } if (number > 0) { parsedNumbers.Add(number); } if (parsedNumbers.Count == 0) { Console.WriteLine(string.Format("Case #{0}: {1}", j + 1, 0)); } else { List <int> numbers = new List <int>(); List <uint> sequenceCounts = new List <uint>(); sequenceCounts.Add(1); /// Count numbers using recursive formula for (int i = parsedNumbers.Count - 1; i >= 0; i--) { SolveCounting(M, parsedNumbers[i], numbers, sequenceCounts); } /// For small inputs use exhaustive search for verification if (parsedNumbers.Count < 15) { LinkedList <int> input = new LinkedList <int>(parsedNumbers); if (sequenceCounts.Last() != (1 + SolveEnumerating(M, input.First, input)) % 0xfaceb00c) { Console.WriteLine(string.Format("Case #{0}: {1}", j + 1, "Error")); } } Console.WriteLine(string.Format("Case #{0}: {1}", j + 1, sequenceCounts.Last())); } } }