和网上的做法都不一样;
找一下规律
我们只要知道某个区间内有哪个点是不合法的就行了,然后就可以“递归”确定第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; }