gym100851

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章