NUMTSN-369 NumbersNo Tags
7.369 numbers
A number is said to be a 369 number if
- The count of 3s is equal to count of 6s and the count of 6s are equal to count of 9s.
- The count of 3s is at least 1.
For Example 12369, 383676989, 396 all is 369 numbers whereas 213, 342143, 111 is not.
Given A and B find how many 369 numbers is there in the interval [a, b]. Print the answer modulo 1000000007.
Input
The first line contains the number of test cases (T) followed to T lines each containing 2 integers A and B.
Output
For each test case output the number of 369 numbers between A and B inclusive.
Constraints
t<=100
1<=a<=b<=10^50
Sample Input
3
121 4325
432 4356
4234 4325667
Sample Output
60
58
207159
Links: http://www.spoj.com/problems/NUMTSN/en/
/ *
Intent: find the number of the same number (and at least 1) in a range of 3 6 9
Idea: Note that the number is very large, with a power of 10 ^ 50, so save it with a string
The digits dp dp [i] [j] [k] [m] represent the numbers up to the i-th position, 3 6 9
* /
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define L (x) (x << 1)
#define R (x) (x << 1 | 1)
#define MID (x, y) ((x + y) >> 1)
#define bug printf ("hihi \ n")
#define eps 1e-8
typedef long long ll;
using namespace std;
#define N 55
#define mod 1000000007
ll dp [N] [N] [N] [N]; //
int bit [N];
void change (char * a)
{
int i, j;
int len = strlen (a);
len--;
while (len> = 0)
{
a [len]-;
if (a [len]> = '0') break;
a [len] = '9';
len--;
}
len = strlen (a);
for (i = 0; i <len-1; i ++) if (a [i]> = '1') break;
int k = 0;
for (i; i <len; i ++)
a [k ++] = a [i];
a [k] = '\ 0';
}
ll dfs (int pos, int le, int mid, int ri, bool bound)
{
if (pos == 0) return le == mid && mid == ri && le> = 1? 1: 0;
if (! bound && dp [pos] [le] [mid] [ri]> = 0) return dp [pos] [le] [mid] [ri];
int up = bound? bit [pos]: 9;
ll ans = 0;
for (int i = 0; i <= up; i ++)
{
if (i == 3)
ans = (ans + dfs (pos-1, le + 1, mid, ri, bound && i == up))% mod;
else
if (i == 6)
ans = (ans + dfs (pos-1, le, mid + 1, ri, bound && i == up))% mod;
else
if (i == 9)
ans = (ans + dfs (pos-1, le, mid, ri + 1, bound && i == up))% mod;
else
ans = (ans + dfs (pos-1, le, mid, ri, bound && i == up))% mod;
}
if (! bound) dp [pos] [le] [mid] [ri] = ans;
return ans;
}
ll solve (char * c)
{
int i, j;
int len = strlen (c);
for (i = 1; i <= len; i ++)
bit [i] = c [len-i]-'0';
return dfs (len, 0,0,0, true)% mod;
}
int main ()
{
int i, j, t;
char a [N], b [N];
memset (dp, -1, sizeof (dp));
scanf ("% d", & t);
while (t--)
{
scanf ("% s% s", a, b);
change (a);
printf ("% lld \ n", (solve (b) -solve (a) + mod + mod)% mod); // must + mod% mod because it may be negative
}
return 0;
}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Spoj NUMTSN NUMTSN-369 Numbers (digital DP)