和网上的做法都不一样;
找一下规律
我们只要知道某个区间内有哪个点是不合法的就行了,然后就可以“递归”确定第k个值了
设ans[k]表示串长度为k的时候,一共有多少不合法串;
这个规律可以从二进制的角度考虑,当串的长度由k变成(k+1)的时候,按字典序排列的(递增二进制数)串的个数由2^k 变成了2^(k+1),所以ans[k+1] 在包含了ans[k] 的同时,后面的(2^k)个数字相当于前面的(2^k)个数字最前面加上了0和1
。。。暂时这样,待续,,有看到的自己推一下吧,,找女朋友去了;
#include<bits/stdc++.h>
using namespace std;
const int maxn = 40 + 7, maxd = 3000 + 7;;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n, k;
ll ans[maxn];
void init() {
ll a = 0, b = 0, c = 1;
ans[1] = 0;
for(int i = 2; i < 44; ++i) {
ans[i] = ans[i-1] + a + c;
c *= 2;
a = ans[i-1];
}
}
int main() {
init();
cin >> n >> k;
ll tt = (1LL<<(n)) - ans[n];
if(tt < k) { cout << -1; return 0; }
for(int i = n; i >= 1; --i) {
ll t = (1LL<<(i-1))-ans[i-1];
if(k <= t) { cout << 0; }
else { cout << 1; k -= t; }
}
return 0;
}