https://codeforces.com/gym/100851/my
打表可以發現任何一個可能的答案,它的後綴也是正確答案。所以可以通過搜索求得解。初始的正解集合是{0,1},然後枚舉這些正解,在它的前面加上0,判斷是否滿足要求,將其加入到集合p中。再次枚舉正解,在前面加上1,判斷是否滿足要求。如果滿足,那麼正確答案數加一,將其加入到集合p中。將p作爲下一次的正解集合,重複以上的步驟,直到找到第n個答案爲止。
直接計算的話會爆ull,所以用字符串存儲。使用高精除以單精的方法計算十進制的末尾數字,和二進制的數字比較即可。
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vec;
int n;
bool check(vec ve){
int le=ve.size();
vec tmp=ve;
for (int i=0; i<ve.size(); i++){
int x0=ve[i];
if (x0!=tmp[0]%2) return 0;
int c=0;
for (int j=le-1; j>=0; j--){
int op=c*10+tmp[j];
tmp[j]=op/2;
c=op%2;
}
while (tmp[le-1]==0) le--;
}
return 1;
}
void bfs(){
int ans=1;
queue<vec> p;
vector<vec> p0;
vec ini;
ini.push_back(0);
p.push(ini);
ini[0]=1;
p.push(ini);
while (1){
// printf("fjief\n");
p0.clear();
while (!p.empty()) p0.push_back(p.front()),p.pop();
for (int i=0; i<p0.size(); i++){
// printf("fkdfj\n");
vec ve=p0[i];
ve.push_back(0);
if (check(ve)) p.push(ve);
}
for (int i=0; i<p0.size(); i++){
vec ve=p0[i];
ve.push_back(1);
if (check(ve)){
p.push(ve);
ans++;
if (ans==n) {
for (int j=ve.size()-1; j>=0; j--)
printf("%d",ve[j]);
printf("\n");
return;
}
}
}
}
}
int main()
{
freopen("binary.in","r",stdin);
freopen("binary.out","w",stdout);
cin>>n;
if (n==1) {
printf("1\n");
return 0;
}
bfs();
return 0;
}