zoukankan      html  css  js  c++  java
  • URAL 1233 Amusing Numbers 好题

    参照了nocow上的解法,照搬过来……

    易知一个数X在数列中在另一个数Y前,当且仅当X前缀小于Y或前缀相等X短,那么我们分布考虑,比如对于数48561:

    5位上:10000~48560;

    4位上:1000~4856;

    3位上:100~485;

    2位上:10~48;

    1位上:1~4.

    这样我们就得到了1..N中48561的位置,可以用这个来判错.

    接下来的方法类似,为了使得我们的N满足要求,我们必须去找比48561大且前缀比其小的数,同样有:

    6位上:100000~485609;  //注意红色部分比原数减少了1,之前没注意这里一直WA……

    ……

    ---------------------以上nocow上给出的题解-----------------------

    判断无解的情况:

    1.当K != 10^x 时,假设到 K 时前面已经有的数的个数是cnt,如果 M - 1 < cnt 则无解。

    2.当K == 10^x 时,K前面最多只有x个数,M - 1 > x 则无解。

    一组数据:

    1150 27350

    12 2

    20 13

    3 23

    3 3

    100 3

    输出:

    1010679

    0

    20

    29

    3

    100

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    
    #define LL unsigned long long int
    
    using namespace std;
    
    const int MAXN = 30;
    
    LL K, M, cnt;
    LL bit[MAXN];
    char strK[MAXN], strM[MAXN];
    bool ok, find;
    
    void init()
    {
        bit[0] = 1;
        for ( int i = 1; i < MAXN; ++i )
            bit[i] = bit[i - 1] * (LL)10;
        return;
    }
    
    void chuli()
    {
        cnt = 0;
        int len = strlen( strK );
        for ( int i = 1; i <= len; ++i )
        {
            //printf( "###%I64u %I64u
    ", K / bit[ len - i ], bit[i - 1] );
            cnt += K / bit[ len - i ] - bit[i - 1] + 1;
        }
        --cnt;
        //printf("**%I64u %I64u
    ", cnt, M );
        if ( cnt > M - 1 ) ok = false;
        return;
    }
    
    LL GetAns()
    {
        LL cur = K;
    
        if ( cnt == M - 1 ) return cur;
        --cur;
    
        int i;
        for ( i = strlen(strK); ; ++i )
        {
            cur = cur * 10 + 9;
            //printf( "~~~%20I64u %20I64u
    ", cur, bit[i] );
            LL tmp = cnt + cur - bit[i] + 1;
            //printf( "tmp=%I64d
    ", tmp );
            if ( tmp == M - 1 ) return cur;
            if ( tmp >= M ) break;
            cnt = tmp;
        }
    
        return bit[i] + M - 1 - cnt - 1;
    }
    
    bool SpecialJudge()
    {
        int len = strlen(strK);
        find = false;
        for ( int i = 0; i <= len; ++i )
        {
            if ( K == bit[i] )
            {
                find = true;
                break;
            }
        }
        if ( !find ) return true;
        if ( M - 1 > cnt ) return false;
        return true;
    }
    
    int main()
    {
        //freopen( "out.txt", "r", stdin );
        //freopen( "s1.txt", "w", stdout );
        init();
        while ( scanf( "%s", strK ) == 1 )
        {
            scanf( "%I64u", &M );
            sscanf( strK, "%I64u", &K );
    
            ok = true;
            LL ans;
            chuli();
    
            if ( !SpecialJudge() )
            {
                puts("0");
                continue;
            }
            if ( find )
            {
                if ( cnt == M - 1 ) printf( "%I64u
    ", K );
                else puts("0");
                continue;
            }
    
            if ( ok ) ans = GetAns();
            if ( ok ) printf( "%I64u
    ", ans );
            else puts("0");
        }
        return 0;
    }
  • 相关阅读:
    STS 创建 Maven 项目填坑
    JeeSite | 访问控制权限
    《Spring + MyBatis 企业应用实战》书评
    MyBatis-Generator 用法介绍
    Java描述数据结构之链表的增删改查
    Java中的Object类的几个方法
    设计模式之策略模式(Strategy Pattern)
    设计模式之模板方法(Template Method)
    JeeSite | 数据分页与翻页
    day 19
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3240074.html
Copyright © 2011-2022 走看看