• poj 3208 找出第n个包含666连续字串的数字


    说白了,只要求出1-x中出现666子串的数字,然后二分枚举答案。

    View Code
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 typedef long long LL;
     6 int const N = 20;
     7 LL dp1[N][N][N],dp2[N][N][N];
     8 int bit[N],ln;
     9 LL getsum1(int t,int pre,int last,int flag,int limit)
    10 {
    11    if(!t)return flag;
    12    int up=(limit?bit[t]:9);
    13    LL ans=0;
    14    if(!limit&&flag&&dp1[t][pre][last]!=-1)return dp1[t][pre][last];
    15    if(!limit&&!flag&&dp2[t][pre][last]!=-1)return dp2[t][pre][last];
    16    for(int i=0;i<=up;i++)
    17    {
    18        int f=0;
    19        if(flag||(pre==6&&last==6&&i==6))f=1;
    20        ans+=getsum1(t-1,last,i,f,limit&&i==up);
    21    }
    22    if(!limit&&flag&&dp1[t][pre][last]==-1)dp1[t][pre][last]=ans;
    23    if(!limit&&!flag&&dp2[t][pre][last]==-1)dp2[t][pre][last]=ans;
    24    return ans;
    25 }
    26 LL getsum2(LL n)
    27 {
    28    for(ln=0;n;bit[++ln]=n%10,n/=10);
    29    return getsum1(ln,0,0,0,1);
    30 }
    31 int main()
    32 {
    33     int T;
    34     scanf("%d",&T);
    35     LL l,r,n,ans,mid;
    36     memset(dp1,-1,sizeof(dp1));
    37     memset(dp2,-1,sizeof(dp2));
    38     while(T--)
    39     {
    40           scanf("%I64d",&n);
    41           l=666LL,r=66600000000LL;
    42           while(l<r)
    43           {
    44                 mid=(l+r)>>1;
    45                 LL x=getsum2(mid);
    46                 if(x>=n)
    47                 r=mid;
    48                 else
    49                 l=mid+1;
    50           }
    51           printf("%I64d\n",l);
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    2014-7 Andrew Ng 自动化所报告听后感
    转百度前辈的Trados使用心得
    回文数
    整数反转
    无重复字符的最长子串
    vim配色
    mysql 遇到的问题&错误总结
    Ubuntu更换软件源
    各数据类型在64位32位系统占字节数
    不得不说fdm真的好用
  • 原文地址:https://www.cnblogs.com/nuoyan2010/p/3066819.html
Copyright © 2020-2023  润新知