http://acm.hdu.edu.cn/showproblem.php?pid=6468
题目
今天zyb参加一场面试,面试官听说zyb是ACMer之后立马抛出了一道算法题给zyb:
有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?
例如n=15,k=7, 排列顺序为1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9;那么第7个数字就是15.
那么,如果你处在zyb的场景下,你能解决这个问题吗?
Input
T组样例(T<=100)
两个整数n和k(1<=n<=1e6,1<=k<=n),n和k代表的含义如上文
Output
输出1-n之中字典序第k小的数字
Sample Input
1 15 7
Sample Output
15
题解
类似于编码树
然后通过遍历层来计算节点数
做题做傻了= =
另外我发现inline不一定是真的内联,所以还是define内联靠谱(斜眼笑)
AC代码
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<iomanip> #include<vector> #define REP(r,x,y) for(register int r=(x); r<(y); r++) #define REPE(r,x,y) for(register int r=(x); r<=(y); r++) #define PERE(r,x,y) for(register int r=(x); r>=(y); r--) #ifdef sahdsg #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) (void)0 #endif using namespace std; typedef long long LL; typedef pair<LL, LL> pll; typedef pair<int, int> pii; template <class T> inline void read(T& x) { char c=getchar(); int f=1; x=0; while(!isdigit(c)&&c!='-') c=getchar(); if(c=='-')f=-1,c=getchar(); while(isdigit(c)) {x=x*10+c-'0';c=getchar();} x*=f; } int k; int n; inline void go() { int i=1; k--; while(k) { int f=i,t=i+1; int cnt=0; while(f<=n) { cnt+=t-f; t=min(t*10,n+1); f*=10; } if(cnt<=k) { i++; k-=cnt; } else { i*=10; k--; } } printf("%d ", i); } int main() { int t; read(t); while(0<t--) { read(n); read(k); go(); } return 0; }