← Home
For problem statement at 0-999/0-99/90-99/95/problemD.txt this is a correct solution, but verifier at 0-999/0-99/90-99/95/verifierD.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
)

const MOD int64 = 1000000007

func decString(s string) string {
	if s == "0" {
		return "0"
	}
	b := []byte(s)
	i := len(b) - 1
	for i >= 0 && b[i] == '0' {
		b[i] = '9'
		i--
	}
	if i >= 0 {
		b[i]--
	}
	j := 0
	for j < len(b)-1 && b[j] == '0' {
		j++
	}
	return string(b[j:])
}

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var t, k int
	fmt.Fscan(in, &t, &k)

	l := make([]string, t)
	r := make([]string, t)
	maxLen := 1
	for i := 0; i < t; i++ {
		fmt.Fscan(in, &l[i], &r[i])
		if len(l[i]) > maxLen {
			maxLen = len(l[i])
		}
		if len(r[i]) > maxLen {
			maxLen = len(r[i])
		}
	}

	ns := 0
	far := k + 1
	succ := k + 2
	S := k + 3

	trans := make([][10]int, S)
	for st := 0; st < S; st++ {
		for d := 0; d <= 9; d++ {
			lucky := d == 4 || d == 7
			if st == succ {
				trans[st][d] = succ
			} else if st == ns {
				if d == 0 {
					trans[st][d] = ns
				} else if lucky {
					trans[st][d] = 1
				} else {
					trans[st][d] = far
				}
			} else {
				g := st
				if lucky {
					if g <= k {
						trans[st][d] = succ
					} else {
						trans[st][d] = 1
					}
				} else {
					ng := g + 1
					if ng > far {
						ng = far
					}
					trans[st][d] = ng
				}
			}
		}
	}

	ways := make([][]int64, maxLen+1)
	for i := range ways {
		ways[i] = make([]int64, S)
	}
	ways[0][succ] = 1

	for rem := 1; rem <= maxLen; rem++ {
		prev := ways[rem-1]
		cur := ways[rem]
		for st := 0; st < S; st++ {
			var sum int64
			for d := 0; d <= 9; d++ {
				sum += prev[trans[st][d]]
			}
			cur[st] = sum % MOD
		}
	}

	countLE := func(s string) int64 {
		if s == "0" {
			return 0
		}
		state := ns
		var ans int64
		n := len(s)
		for i := 0; i < n; i++ {
			curDigit := int(s[i] - '0')
			rem := n - 1 - i
			for d := 0; d < curDigit; d++ {
				ans += ways[rem][trans[state][d]]
			}
			ans %= MOD
			state = trans[state][curDigit]
		}
		if state == succ {
			ans++
		}
		return ans % MOD
	}

	for i := 0; i < t; i++ {
		left := decString(l[i])
		ans := (countLE(r[i]) - countLE(left)) % MOD
		if ans < 0 {
			ans += MOD
		}
		fmt.Fprintln(out, ans)
	}
}