1. 程式人生 > >HDU - 2089 不要62 【暴力打表】【數位DP】

HDU - 2089 不要62 【暴力打表】【數位DP】

不要62 HDU - 2089

題意

求區間【n,m】之間有多少個數字不含4或者連續的62

解法1

由於資料範圍是0~1e6,所以直接暴力判斷每一位數字是否含有4或者62,然後求字首和即可

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<map>
#include<vector>
using
namespace std; #define inf 0x3f3f3f3f #define ll long long const int maxn=1e6+10; int f[maxn]; //若X是不吉利數字,返回true bool judge1(int x){ while(x){ if(x%10==4||x%100==62) return true; x/=10; } return false; } //若X是不吉利數字,返回true bool judge2(int x){ char p[20]; sprintf(p,
"%d",x); int len=strlen(p); if(p[0]=='4') return true; for(int i=1;i<len;i++){ if(p[i]=='4') return true; if(p[i-1]=='6'&&p[i]=='2') return true; } return false; } void init(){ f[1]=1; for(int i=2;i<maxn;i++){ if
(!judge1(i)) f[i]=f[i-1]+1; else f[i]=f[i-1]; } } int main(){ int n,m; init(); while(scanf("%d%d",&n,&m)!=EOF&&n&&m){ printf("%d\n",f[m]-f[n-1]); } }

解法2

數位動態規劃

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<cstdio>
#include<string>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#define mod 998244353
#define INF 0x3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
const int maxn=10;
int bit[maxn];
int dp[maxn][3];//[len][x]
//0->luck
//1->luck and highest is 2
//2->unluck
//初始化DP陣列,表示前i位的三種情況
void init(){
    dp[0][0]=1;
    dp[0][1]=0;
    for(int i=1;i<=maxn-1;i++){
        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0];
    }
}
int solve(int num){
    int len=0,rec=num,ans,flag;
    //get bit array
    while(num){
        bit[++len]=num%10;
        num/=10;
    }
    bit[len+1]=0;

    ans=0;//the unluck number
    flag=0;//if appear unluck

    for(int i=len;i>=1;i--){
        ans+=dp[i-1][2]*bit[i];
        if(flag)
            ans+=dp[i-1][0]*bit[i];
        else{
            if(bit[i]>4)
                ans+=dp[i-1][0];
            if(bit[i]>6)
                ans+=dp[i-1][1];
            if(bit[i+1]==6&&bit[i]>2)
                ans+=dp[i][1];
        }
        if(bit[i]==4||(bit[i+1]==6&&bit[i]==2))
            flag=1;
    }
    return rec-ans;
}
int main(){
    init();
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF&&n&&m){
        printf("%d\n",solve(m+1)-solve(n));
    }
}