Description
8是中国人很喜欢的一个数字,但是如果有3的存在就变成了38,就不是很好了。。
你能告诉我,在[L, R] 的正整数区间内,要么包含3 要么包含 8 的不同的整数有多少个么?
Input
第一行一个整数T (T ≤ 10000),代表数据的组数
对于每组数据给两个整数 L, R (1 ≤ L ≤ R ≤ 1e9)
Output
对于每组数据,给一个整数为答案。
Sample Input
3 1 100 1 3 8 8
Sample Output
34 11
数位dp
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; int p[11],l,r; struct abc { int x,y,z; }f[11][10]; void init() { f[1][3].x=1; f[1][8].y=1; for (int i=p[1]=1;i<=10;i++) p[i+1]=10 * p[i]; for (int i=2;i<=10;i++) { for (int j=0;j<10;j++) { if (j==3) { f[i][j].x=p[i]; for (int k=0;k<10;k++) { f[i][j].y+=f[i-1][k].y; f[i][j].z+=f[i-1][k].y; } } else if (j==8) { f[i][j].y=p[i]; for (int k=0;k<10;k++) { f[i][j].x+=f[i-1][k].x; f[i][j].z+=f[i-1][k].x; } } else { for (int k=0;k<10;k++) { f[i][j].y+=f[i-1][k].y; f[i][j].x+=f[i-1][k].x; f[i][j].z+=f[i-1][k].z; } } } } } int get(int x) { int digit[11],ws=0,ans=0,f1=1,f2=1; while (x) digit[++ws]=x%10,x/=10; for (int i=ws;i;i--) { if (f1&&f2) for (int j=0;j<digit[i];j++) { ans+=f1*f[i][j].x+f2*f[i][j].y-(f1+f2)*f[i][j].z; } else if (f1) for (int j=0;j<digit[i];j++) { ans+=p[i]-f[i][j].y; } else if (f2) for (int j=0;j<digit[i];j++) { ans+=p[i]-f[i][j].x; } if (digit[i]==3) f2=0; if (digit[i]==8) f1=0; if (f1==0&&f2==0) break; } return ans; } int main() { init(); int T; scanf("%d",&T); while (T--) { scanf("%d%d",&l,&r); cout<<get(r+1)-get(l)<<endl; } }
温故而知新
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define fi first #define se second #define mp(i,j) make_pair(i,j) #define pii pair<int,int> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-8; const int INF = 0x7FFFFFFF; const int mod = 10000; const int N = 20; const int read() { char ch = getchar(); while (ch<'0' || ch>'9') ch = getchar(); int x = ch - '0'; while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0'; return x; } int T, l, r, f[10][3], a[N]; int solve(int x) { int tot = 0; if (x == 0) return 0; while (x) a[++tot] = x % 10, x /= 10; int f1 = 0, f2 = 0, ans = 0; per(i, tot, 1) { if (f1&&f2) return ans; rep(j, 0, a[i] - 1) { if (f1) ans += (j != 8)*(f[i - 1][0] + f[i - 1][1]); if (f2) ans += (j != 3)*(f[i - 1][0] + f[i - 1][2]); if (!f1 && !f2) { ans += (j == 3 || j == 8)*f[i - 1][0] + (j != 8)*f[i - 1][1] + (j != 3)*f[i - 1][2]; } } f1 |= a[i] == 3; f2 |= a[i] == 8; } return ans + (f1 + f2 == 1); } int main() { f[0][0] = 1; rep(i, 1, 10) { rep(j, 0, 9) { f[i][0] += (j != 3 && j != 8) * f[i - 1][0]; f[i][1] += (j == 3) * f[i - 1][0] + (j != 8) * f[i - 1][1]; f[i][2] += (j == 8) * f[i - 1][0] + (j != 3) * f[i - 1][2]; } } T = read(); while (T--) { scanf("%d%d", &l, &r); printf("%d\n", solve(r) - solve(l - 1)); } return 0; }