POJ3208Apocalypse Someday(数位DP)

某教练考试出的题的原型。。。

暴力也能骗不少分呢。

解释都在代码里(大佬的代码0msAC可还行。。。)

改一改就过了考试题妈耶。。。。

#include<bits/stdc++.h>
using namespace std;
int n,f[20][20],p,g[20][20],m=1;//g数组表示处在第i个状态时接收字符j时转移的状态 
int read(){//f[i][j]表示从j状态走i步能够查询到的含666的数的个数 ,既长度为i位的数字有多少个666数 
    int x=0,k=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*k; 
} 
int main() {
    for(int i=0;i<3;i++){
        g[i][6]=i+1; //当填入的字符是6是,状态移动到下一步 
    } 
    for(int i=0;i<10;i++){
        g[3][i]=3;//已经填好3个6,剩下的你随意填 
    } 
    f[0][3]=1;//666的情况?
    for(int i=1;i<=10;i++){
        for(int j=0;j<4;j++){
            for(int k=0;k<10;k++){
                f[i][j]+=f[i-1][g[j][k]]; 
            } 
        } 
    } 
    int t=read();
    while(t--){
        scanf("%d",&n); p=0;
        for(m=1;m<11&&f[m][0]<n;m++);
        for(int i=m,j;i>0;i--){
            for(j=0;j<10;j++){
                if(n>f[i-1][g[p][j]]){
                   n-=f[i-1][g[p][j]]; 
                } else{
                   break;
                } 
            } 
            printf("%d",j);
            p=g[p][j]; 
        } 
        printf("\n"); 
    } 
    return 0;
} 

 

posted @ 2019-10-26 16:42  wilxx  阅读(105)  评论(0编辑  收藏  举报