参照了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; }