NOIP模拟赛 准考证号

                            准考证号 128M 0.1s ticket.cpp

escription

蒟蒻hzwer NOIP2014惨跪,他依稀记得他的准考证号是37,现在hzwer又将要面临一场比赛,他希望准考证号不出现37(连续),同时他又十分讨厌4,所以也不希望4出现在准考证号中。。。现在他想知道在A和B之间有多少合法的准考证号

Input

包含两个整数,A B

Output

一个整数。

Sample Input

【输入样例一】
1 10
【输入样例二】
25 50

Sample Output

【输出样例一】
9
【输出样例二】
14
【数据规模和约定】
20%的数据,满足 1 <= A <= B <= 1000000 。
100%的数据,满足 1 <= A <= B <= 2000000000 。

 

F[i][j]表示第i位数字为j的方案数

黄学长原谅我这么弱。。。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int A,B;
 5 int base[15];
 6 int F[15][10];
 7 
 8 inline void pre()
 9 {
10     base[1]=1;
11     for(int i=2;i<=10;i++) base[i]=base[i-1]*10;
12     for(int i=0;i<10;i++) if(i!=4) F[1][i]=1;
13     for(int i=2;i<=10;i++)
14         for(int j=0;j<10;j++)
15             for(int k=0;k<10;k++)
16                 if(j!=4&&k!=4&&(j!=3||k!=7))
17                     F[i][j]+=F[i-1][k];
18 }
19 
20 inline int calc(int x)
21 {
22     if(x==0) return 0;
23     int L=10,pre=0,cur=0,ans=0;
24     while(base[L]>x) L--;
25     for(int i=1;i<L;i++)
26         for(int j=1;j<10;j++)
27             ans+=F[i][j];
28     cur=x/base[L];x%=base[L];
29     if(L==1)
30         for(int i=1;i<=cur;i++)
31             ans+=F[L][i];
32     else
33         for(int i=1;i<cur;i++)
34             ans+=F[L][i];
35     pre=cur;
36     for(int i=L-1;i;i--)
37     {
38         if(cur==4) break;
39         cur=x/base[i];x%=base[i];
40         if(i==1)
41         {
42             for(int j=0;j<=cur;j++)
43                 if(pre!=3||j!=7)
44                     ans+=F[i][j];
45         }
46         else
47         {
48             for(int j=0;j<cur;j++)
49                 if(pre!=3||j!=7)
50                     ans+=F[i][j];
51         }
52         if(pre==3&&cur==7)break;
53         pre=cur;
54     }
55     return ans;
56 }
57 
58 int main()
59 {
60     cin>>A>>B;
61     pre();
62     cout<<calc(B)-calc(A-1);
63 }
原文地址:https://www.cnblogs.com/InWILL/p/5970966.html