题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089
题意
求一个区间内,不出现4和连续的62的数的个数。
分析
可以暴力打表。也可以数位DP。
设:
dp[i][0],表示长度为i,不存在不吉利数字
dp[i][1],表示长度为i,不存在不吉利数字,且最高位为2
dp[i][2],表示长度为i,存在不吉利数字
状态定义好了,转移比较简单。
在计算时,按位分解,考虑当前位能否放4或6,详情看代码。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #include<cstring> #include<queue> #include<vector> #include<bitset> #include<map> #include<deque> #include<stack> using namespace std; typedef pair<int,int> pii; #define X first #define Y second #define pb push_back #define mp make_pair typedef long long ll; #define ms(a,b) memset(a,b,sizeof(a)) const int inf = 0x3f3f3f3f; const int maxn = 1e6; const int mod = 1e9+7; #define lson l,m,2*rt #define rson m+1,r,2*rt+1 int dp[10][3]; void init(){ dp[0][0]=1; dp[0][1]=dp[0][2]=0; for(int i=1;i<7;i++){ dp[i][0]=9*dp[i-1][0]-dp[i-1][1]; //在最高位加上除4以外的9个数字,但要减掉2之前加上6 dp[i][1]=dp[i-1][0]; //在不含不吉利数字的最高位加上2 dp[i][2]=dp[i-1][0]+dp[i-1][1]+10*dp[i-1][2];
//在已有不吉利数字前加任意数字,或者无不吉利数字的最高位加4,或者在2前面加6 } } int bit[10]; int solve(int x){ int t=x; int len=0; while(t){ bit[++len]=t%10; t/=10; } bit[len+1]=0; int ans=0; bool flag=false; for(int i=len;i>=1;i--){ ans += dp[i-1][2]*bit[i]; if(flag) ans+=dp[i-1][0]*bit[i]; //高位已经出现4或者62,后面随意 else{ if(bit[i]>4) ans+=dp[i-1][0]; if(bit[i+1]==6&&bit[i]>2) ans+=dp[i][1]; if(bit[i]>6) ans+=dp[i-1][1]; } if(bit[i]==4 || (bit[i+1]==6&&bit[i]==2)) flag=true; } if(flag) ans++; return x-ans; } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL int l,r; init(); while(scanf("%d%d",&l,&r)&&(l||r)){ printf("%d\n",solve(r)-solve(l-1)); } return 0; }
以下是暴力打表的代码
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #include<cstring> #include<queue> #include<vector> #include<bitset> #include<map> #include<deque> #include<stack> using namespace std; typedef pair<int,int> pii; #define X first #define Y second #define pb push_back #define mp make_pair typedef long long ll; #define ms(a,b) memset(a,b,sizeof(a)) const int inf = 0x3f3f3f3f; const int maxn = 1e6; const int mod = 1e9+7; #define lson l,m,2*rt #define rson m+1,r,2*rt+1 int dp[maxn+5]; void init(){ dp[0]=0; for(int i=1;i<maxn;i++){ dp[i]=dp[i-1]; bool f=0; int pre=0; int x=i; while(x){ if(x%10==4){ f=1; break; }else if(pre==2&&x%10==6){ f=1; break; } pre=x%10; x/=10; } if(f){ dp[i]++; } } } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL int l,r; init(); while(scanf("%d%d",&l,&r)&&(l||r)){ printf("%d\n",r-l+1-(dp[r]-dp[l-1])); } return 0; }
原文:https://www.cnblogs.com/fht-litost/p/8969961.html