题目链接:http://codeforces.com/gym/101194
题意:定义半回文数a为将二进制数a的奇数位和偶数位分别提出来,如果奇数位或者偶数位为回文数则a为半回文数,求长度为n的第k个半回文数
这个题目需要思考一下DP状态应该是什么,直接dfs应该是不行的,因为这个后效性要去除比较困难,不过好在这题对数的大小没有限制,所以可以不用dfs做了。。
然后猴了n遍后发现,要处理填完前i位的条件下的半回文数个数,这个可以分为偶数位回文和奇数位回文和奇偶都回文容斥一下就可以。。
然后从高到低就分别决定各个位的01即可。。
是个反套路的数位DP,依赖套路会花很多时间。。
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━━━━━━━━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<set>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define NM 100005
#define nm 1055
#define pi 3.1415926535897931
const ll inf=4e18;
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,ans[NM],ca;
ll k,p[64];
bool odd,even,_odd,_even;
ll get(int x){if(x<62)return p[x];else return inf;}
bool bit(int x){
if(n%2)return ans[n-x+1]==-1||ans[n-x+1]==ans[x];
if(x%2)return ans[n-x]==-1||ans[n-x]==ans[x];
else return ans[n-x+2]==-1||ans[n-x+2]==ans[x];
}
ll calc(int t){
ll s=0;
if(_even)s+=get( max( (n/2+1)/2-t/2 ,0) + (n+1)/2-(t+1)/2);
if(_odd)s+=get( max( ((n+1)/2+1)/2-(t+1)/2 ,0) + n/2-t/2);
if(_even&&_odd)s-=get( max( ((n+1)/2+1)/2-(t+1)/2 ,0) + max(0,(n/2+1)/2-t/2));
return s;
}
int main(){
p[0]=1;inc(i,1,62)p[i]=p[i-1]<<1;
int _=read();while(_--){
n=read();k=read();
odd=even=_odd=_even=true;
printf("Case #%d: ",++ca);
if(calc(0)<k){printf("NOT FOUND!\n");continue;}
inc(i,1,n)ans[i]=-1;
inc(i,1,n){
ll s=0;
ans[i]=0;
_odd=odd;_even=even;
if(i%2)_odd=odd&&bit(i);else _even=even&&bit(i);
s=calc(i);
if(s==0||s<k)k-=s,ans[i]=1;
if(i%2)odd=odd&&bit(i);else even=even&&bit(i);
}
inc(i,1,n)printf("%d",ans[i]);putchar('\n');
}
return 0;
}