hiho 1182 : 欧拉路·三
1182 : 欧拉路·三
这时题目中给的提示:
小Ho:是这样的,每次转动一个区域不是相当于原来数字去掉最左边一位,并在最后加上1或者0么。
于是我考虑对于"XYYY",它转动之后可以变成"YYY0"或者"YYY1"。我就将所有的数字0~2^N-1看作2^N个点,连接所有的("XYYY","YYY0"),("XYYY","YYY1")。
比如当N=3时,我得到了这样一个图:

我要做的就是找一条路径,从一个点出发,走过所有的点后,再回到起点。但是我发现好像很难的样子。
小Hi:那当然了。你这样构造出来的路径叫做哈密顿回路,不是那么容易可以求解的。
小Ho:哎??那我应该怎么做。
小Hi:其实你的想法是没问题的,但是需要进行一下变换。在你的构图中我们是用点来表示数字,所以需要经过每一个点。如果我们用边来表示每一个数字呢?
小Ho:怎么用边表示数字?
小Hi:其实也很简单,比如说数字"10011",分别删掉它第一个数字和最后一个数字,得到"1001","0011"。然后我们连接一条从"1001"到"0011"的有向边,表示数字"10011"。则我们可以得到构图的方法:
对于N,我们构造一个包含2^(N-1)个点和2^N条边的图,点的编号从0到2^(N-1)-1。编号为i的点表示数字i。对于任意两个点,如果点i,点j满足点i的后n-2个数字和点j的前n-2个数字相同,则我们连接有向边(i,j)。而边(i,j)表示了数字((i << 1)+(j & 1))。比如对于N=3的时候,我们可以得到:

可以很容易证明对于任意不同边(i,j),其表示的数字一定不同。
小Ho:这样构图话,只要找到一条欧拉回路就可以了。但是一定会有欧拉回路么?
小Hi:当然能了,对于有向图,其存在欧拉路的条件是,至多有两个点的入度不等于出度,且这两个点满足:其中一个点入度比出度多1,另一个点出度比入度多1。
若所有点的入度都等于出度,则一定存在欧拉回路。这可以通过和无向图欧拉路同样的方法进行构造证明。
而我们构造的图,由构造方法可以知道对于任意一个点,其入度一定为2,出度一定为2。所以它必定存在欧拉回路。
在有向图中找欧拉路的方法,也仍然可以使用Fleury算法。写成伪代码的话:
DFS(u):
While (以u为起点,且未被删除的边e(u,v))
删除边e(u,v)
DFS(v)
End
PathSize ← PathSize + 1
Path[ PathSize ] ← u
但是,有一点要注意,在使用Fleury算法计算有向图的欧拉路时,我们需要将path[]倒序输出才能得到正确的路径。
小Ho:那找到欧拉回路之后呢?
小Hi:找到欧拉回路之后只要对该条欧拉回路进行拼接就可以得到我们目标的圆盘状态了。
小Ho:好,我大概明白了。我这就来试试!
题目分析:
提示中说的很清楚: 好好看看上面的讲解。 很聪明的地方是把图一变成了图二(图二也就是用边表示n位二进制可以表示的所有数。n=3时, 是0~7),节省了空间。 如果存在一个欧拉回路, 也就是存在一条路径每条边都走过并且只走一遍, 最后回到原点, 那么就可以说这个转盘可以表示n位二进制可以表示的所有数。用fleury求路径, 边球路径边记录,fleury不明白点这里。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std; int n, top, key, final[], ans[];
vector<int> vec[]; void init()//初始化把所有边标记出来
{
for(int i = ; i < ( << n - ); i++)
{
int j = i << ; // 点i向左移一位
int t = << (n - );
j = j & (t - );//舍去第一位
vec[i].push_back(j); //最后一位加0
vec[i].push_back(j+); //最后一位添1
}
}
void dfs(int x)
{
ans[++top] = x;
if(vec[x].size() > )
{
int tmp = vec[x][];
vec[x].erase(vec[x].begin()+);//要记得删除便利过的点
dfs(tmp);
}
}
void fleury(int x)
{
top = ;
ans[top] = x;
while(top > )
{
if(vec[ans[top]].size() > )//如果可扩展, 则dfs可扩展的哪条路线
{
top--;
dfs(ans[top+]);
}
else//该点x没有其他的边可以先走了(即不可扩展), 那么就用final记录下来
{
final[++key] = ans[top];
//ans只是记录路径的中间记录, 可能会变, 一定要用final做最后的记录
top--;
}
}
}
int main()
{
while(scanf("%d", &n) != EOF)
{
for(int i = ; i < ( << n); i++) vec[i].clear();
init();
key = ;
fleury();
for(int i = ; i <= ( << n); i++)//将路径的每个值的最后一个二进制的值求出即可
{
int tmp = final[i] & ;
printf("%d", tmp);
}
cout << endl;
}
return ;
}
hiho 1182 : 欧拉路·三的更多相关文章
- hiho 1182 : 欧拉路·三
1182 : 欧拉路·三 这时题目中给的提示: 小Ho:是这种.每次转动一个区域不是相当于原来数字去掉最左边一位,并在最后加上1或者0么. 于是我考虑对于"XYYY",它转动之后能 ...
- hihoCoder #1182 欧拉路·三 (变形)
题意: 写出一个环,环上有2^n个格子,每个格子中的数字是0或1,相连着的n个格子可以组成一个数的二进制,要求给出这2^n个数字的序列,使得组成的2^n个数字全是不同的.(即从0到2^n-1) 思路: ...
- 【HIHOCODER 1182】欧拉路·三
描述 小Hi和小Ho破解了一道又一道难题,终于来到了最后一关.只要打开眼前的宝箱就可以通关这个游戏了. 宝箱被一种奇怪的机关锁住: 这个机关是一个圆环,一共有2^N个区域,每个区域都可以改变颜色,在黑 ...
- hiho欧拉路·二 --------- Fleury算法求欧拉路径
hiho欧拉路·二 分析: 小Ho:这种简单的谜题就交给我吧! 小Hi:真的没问题么? <10分钟过去> 小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了. 小Hi:哎,我就知道你会遇 ...
- hiho一下 第四十九周 欧拉路·一
[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho近期在玩一个解密类的游戏.他们须要控制角色在一片原始丛林里面探险 ...
- hiho一下 第四十九周 题目1 : 欧拉路·一【无向图 欧拉路问题】
题目1 : 欧拉路·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最 ...
- hiho一下 第四十九周 欧拉路
http://hihocoder.com/contest/hiho49/problem/1 给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路. 一个无向图存在欧拉路当且仅当 ...
- hiho48 : 欧拉路·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的 ...
- 牛客练习赛40 C 小A与欧拉路(树的直径)
链接:https://ac.nowcoder.com/acm/contest/369/C 题目描述 小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点 ...
随机推荐
- 推荐十款非常优秀的 HTML5 在线设计工具
网络有很多优秀的设计和开发工具可能大家都不知道,因此这篇文章就向设计师推荐十款优秀 HTML5 在线工具,这些工具能够帮助设计师们设计出更有创意的作品.随着 HTML5 技术的不断成熟,网络上涌现出越 ...
- python字符串相关的函数
有些是字符串对象的方法,有些是内建库的方法 split分割字符串 find 查找字符串 for c in str: 遍历字符串 len 获取字符串长度 int 将字符串转换成int str ...
- CGContext绘图
0 CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文 1 CGContextMoveToPoint 开始画线 2 CGContex ...
- 很值得学习的java 画图板源码
很值得学习的java 画图板源码下载地址:http://download.csdn.net/source/2371150 package minidrawpad; import java.awt.*; ...
- Codeforces Gym 100425A Luggage Distribution 二分 数学
A - Luggage DistributionTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/c ...
- C++11 新特性之 Lambda表达式
lambda表达式能够用于创建并定义匿名的函数对象,以简化编程工作 Lambda的语法例如以下: [函数对象參数](操作符重载函数參数)->返回值类型{函数体} []内的參数指的是Lambda表 ...
- C++第11周(春)项目2 - 职员有薪水了
课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目2 - 职员有薪水了]定义一个名为CPe ...
- MYSQL内存--------启动mysql缓存机制,实现命中率100% 转
虽然这个标题夸张得过了头,但此文很完整,值得学习.转自 http://www.yy520.net/read.php?278 myql优化,启动MySQL缓存机制,实现命中率100% 配置你的mysql ...
- 结构体定义 typedef struct 用法详解和用法小结
typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...
- 用const取代宏定义更好的管理内存
用const取代宏定义更好的管理内存 宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化.只保存一份到 .rodata 段.甚至有相同后缀的字符串也可以优化 ...