专栏文章

题解:UVA10040 Ouroboros Snake

UVA10040题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minpoqe6
此快照首次捕获于
2025/12/02 06:19
3 个月前
此快照最后确认于
2025/12/02 06:19
3 个月前
查看原文
环形问题很容易想到回路
考虑建立图论模型(技巧点 1),我们将 [0,2n1][0,2^n-1] 中的所有数作为节点,然后向他们能够转移到的节点连边,边权是 0/10/1,分别代表向末尾添加 0/10/1。设当前节点为 xx,则它连向的节点编号为 (x<<1+w)&cover,其中 ww 为边权,covercover掩码,即 1<<(n-1)-1用于提取末尾的 n1n-1。(技巧点 2)
这样建好图之后,跑出字典序最小的欧拉回路,在过程中倒序记录所有的 o(n,k)\operatorname{o}(n,k)(为什么是倒序请参考欧拉回路的实现),然后输出对应的倒数第 kk 个即可。
实现(仅供参考)CPP
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define int long long
using namespace std;

const int N=(1<<25)+5;
int n,k;
int cnt[N];
vector<int> ans;

void dfs(int cur,int cover){
	while(cnt[cur]<2){
		int x=(cur<<1)+cnt[cur];
		cnt[cur]++;
		dfs(x&cover,cover);
		ans.push_back(x);
	}
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	while(cin>>n>>k&&(n+k)){
		memset(cnt,0,sizeof cnt);
		ans.clear();
		int cover=(1<<(n-1))-1;
		dfs(0,cover);
		cout<<ans[ans.size()-1-k]<<'\n';
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...