HDU 6468 zyb的面试

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;
}
原文地址:https://www.cnblogs.com/sahdsg/p/10725730.html