2180: carreras de caballos
Límite de tiempo:
2 segundos
Límite de memoria:
256 MB
Envío: 2 Resuelto: 1
[ Enviar ] [ Estado ] [ Tablero web ]
Descripción
A Petya le gustan mucho las carreras de caballos. En las carreras participan caballos numerados del 1 al r . Petya quiere evaluar la probabilidad de victoria; por alguna razón, para hacer eso necesita saber la cantidad de caballos casi afortunados. Un número casi afortunado es un número entero que tiene al menos dos dígitos afortunados cuya distancia no excede k . Petya aprendió de algunos de sus compañeros de Lviv que los dígitos de la suerte son los dígitos 4 y 7 . La distancia entre los dígitos es la diferencia absoluta entre sus posiciones en el número de un caballo. Por ejemplo, si k = 2 , entonces los números 412395497 , 404 , 4070400000070004007 tienen casi suerte y los números 4 , 4123954997 , 4007000040070004007 no lo son.
Petya preparó intervalos t [ l i , r i ] e inventó el número k , común para todos ellos. Su tarea es encontrar cuántos números casi felices hay en cada uno de estos segmentos. Dado que las respuestas pueden ser bastante grandes, envíelas como módulo 1000000007 ( 10 9 +7 ).
La primera línea contiene dos enteros t y k ( 1≤ t , k ≤1000 ) - el número de segmentos y la distancia entre los números correspondientemente. Las siguientes líneas t contienen pares de enteros l i y r i ( 1≤ l ≤ r ≤10 1000 ). Todos los números se dan sin los ceros iniciales. Los números de cada línea están separados exactamente por un carácter de espacio.
Salida t líneas. En cada línea, imprima un entero: la respuesta para el segmento correspondiente módulo 1000000007 ( 10 9 +7 ).
1 2 1100
4
1 2 70 77
2
2 1 1 20 80100
0 0
En la primera muestra, los cuatro números casi afortunados son 44, 47, 74, 77.
En la segunda muestra, solo 74 y 77 están en el segmento dado.
【análisis】
El significado de la pregunta es muy simple : averigüe el número de dígitos cuyo intervalo entre 4 y 4, 7 y 7, 4 y 7 es menor que k en un intervalo dado.
Digital dp ... es juzgar un poco más, y finalmente juzgar si l es la respuesta, y agregarla. En términos generales, no será t porque siempre que se encuentre el intervalo que cumpla con las condiciones, se marca directamente como verdadero. No es necesario contar 4 y 7
【Código】
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
const int maxn = 1000 + 5;
int dp[maxn][maxn][2];
int bits[maxn];
int t,k;
ll dfs(int len,int lpos,int fg,bool border)
{
if(!len) return fg == 1;
if(!border && dp[len][lpos][fg] != -1) return dp[len][lpos][fg];
int up = border ? bits[len] : 9;
ll res = 0 ;
for (int i = 0; i <= up; i ++) {
if(i == 4 || i == 7)
{
res += dfs(len - 1, len, (lpos && lpos - len <= k) | fg, border && i == up);
}
else res += dfs(len - 1, lpos, fg, border && i == up);
}
res %= mod;
if(!border) dp[len][lpos][fg] = res;
return res;
}
ll f(string s)
{
int len = 0;
for (int i = s.size() - 1; i >= 0; i --) {
bits[++ len] = s[i] - '0';
}
return dfs(len,0,0,1);
}
bool check(string &s)//
{
int p = 0;
for (int i = 1; i <= s.size(); i ++) {
if (s[i - 1] == '4' || s[i - 1] == '7') {
if(!p || i - p > k) p = i;
else if(i - p <= k) return true;
}
}
return false;
}
int main()
{
cin >> t >> k;
string l,r;
memset(dp, -1, sizeof(dp));
for (int i = 0; i < t; i ++) {
cin >> l >> r;
ll ans = f(r) - f(l) + (check(l) ? 1 : 0);
cout << (ans % mod + mod) % mod << endl;//
}
return 0;
}