zoukankan      html  css  js  c++  java
  • Apocalypse Someday

    Apocalypse Someday

    定义一个数是合法的,当且仅当中间出现至少一个连续的大于三个的6,求第x个合法的数,(xleq 50,000,000)

    首先,注意到求第几个,即想到试填法,而试填法关键在于确定了这个状态下的方案数,记住这个,接下来就很好理解了。

    显然要表现长度,又因为要表现合法,于是设(f[i][j])表示有i位的数,状态为j(0表示最高位没有6,1有1个6,2表示有连续的两个6的不合法的数,3表示这是一个合法的数)的方案数,因此不难有

    [f[i][0]=(f[i-1][0]+f[i-1][1]+f[i-1][2]) imes 9 ]

    [f[i][1]=f[i-1][0],f[i][2]=f[i-1][1],f[i][3]=10 imes f[i-1][3]+f[i-1][2] ]

    边界:(f[0][0]=1)

    于是我们可以以此从高位到低位进行试填,数字从小到大,注意特判6,比如填到第i位,此处填了一个6,前面有2个连续的6紧挨着第i位,于是不但(f[i-1][3])为合法的方案,还有(f[i-1][1]+f[i-1][2]),同理可推出前面有1个6,注意前面3个6时,不管这里填什么,方案都是(f[i-1][0]+f[i-1][1]+f[i-1][2]+f[i-1][3])

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define int long long
    using namespace std;
    int dp[21][4];
    il int max(int,int);
    il void read(int&),prepare();
    main(){
        int lsy;read(lsy),prepare();
        while(lsy--){
            int x;read(x);
            int w(0),i,j,t6(0),cnt;
            while(dp[w][3]<x)++w;
            while(w){
                for(i=0;i<10;++i){
                    cnt=dp[w-1][3];
                    if(i==6||t6>2)
                        for(j=max(2-t6,0);j<3;++j)
                            cnt+=dp[w-1][j];
                    if(cnt>=x){putchar(i+48);break;}
                    else x-=cnt;
                }if(i==6)++t6;else if(t6<3)t6&=0;--w;
            }putchar('
    ');
        }
        return 0;
    }
    il int max(int a,int b){
        return a>b?a:b;
    }
    il void prepare(){
        dp[0][0]=1;
        for(int i(1);i<=20;++i)
            dp[i][1]=dp[i-1][0],dp[i][2]=dp[i-1][1],dp[i][3]=10*dp[i-1][3]+dp[i-1][2],
                dp[i][0]=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])*9;
    }
    il void read(int &x){
        x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    }
    
  • 相关阅读:
    linux内核中GNU C和标准C的区别
    linux内核中GNU C和标准C的区别
    Getting start with dbus in systemd (02)
    Getting start with dbus in systemd (01)
    Getting start with dbus in systemd (03)
    物理内存相关的三个数据结构
    数据类型对应字节数(32位,64位 int 占字节数)
    Linux kernel 内存
    共模电感的原理以及使用情况
    [原创]DC-DC输出端加电压会烧毁
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10992509.html
Copyright © 2011-2022 走看看