sgu 101 domino
题意还算简洁明了,加上有道翻译凑过着读完了题。题意大体上是 给你 n 个多米诺骨牌, 给出每个骨牌两端的数字, 只有数字相同才可以推到, 比如 2-3和3-2。你可以旋转这些多米诺骨牌, 输出一个可以全部推到的方案, 如果没有 ,输出 No solution。
第一眼看上去像爆搜, 但是 n 最大到100, 时限竟然只有0.25s,铁定超时, 换个思路, 想不出来, 看了题解,才发现原来是图论题,我们把 0~6 当做点,把每个骨牌当做边, 这样构成了一个图, 我们需要求得就是 遍历所有的边且不重复。
这个可以算是一个 欧拉路 模板题,注意,是 欧拉路, 不是欧拉回路 ,被坑了好久。
欧拉路和欧拉回路都是一笔画问题, 两者都需要满足一个必要条件 : 度数为奇数的要么没有, 要么有2个。 度数就是这个点连得边的条数。
先说欧拉回路, 欧拉回路由于需要回到原点, 所以一定没有度数为奇的点, 只要从任意一点 dfs ,走过的边不再走, 直到无边可走, 就是欧拉回路,此时一定是在原点。
但是,欧拉路不同, 欧拉路可以不回到原点, 这导致 dfs 有可能导致死胡同 , 看一个例子 :
在这个例子里, 如果从 3 开始 dfs, 我们有可能回走到 2 ,然后走到 1, 这时我们发现无路可走了, 但这本应是一个一笔画, 只要从 1 出发就可以了,但是我们在程序里不好判断从哪个点开始, 所以, 引入欧拉路的求法:
从任意一个度数为奇的点开始,仍然 dfs,但是 我们不一开始就把这个点加入答案, 而是先任选和这个点相连的一条边, 继续向下dfs, 然后在把这个店加入答案,就等于是倒序输出。这样很巧妙的解决了上面说的问题。光这么说可能不太好理解,一看代码立刻就能明白。
void ss(int now)
{
遍历每一条和这个点相连的边
{
标记已经走过这条边,以后不再走
ss(和它相邻的点);
把现在这个点加入答案
}
}
如此一来就可以了, 但要注意,要判断此图是否联通, 只需判断你求出的边数和骨牌数是否相等就行了,上代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 110 * 2
#define M 10
using namespace std; int n, du[M] = {};
int p[M], next[N*], v[N*], zheng[N*], bnum = -, kexing[N*], num[N*];
int ans[N][], ansnum = ; void addbian(int x, int y, int now)
{
bnum++; next[bnum] = p[x]; p[x] = bnum;
v[bnum] = y; zheng[bnum] = ; kexing[bnum] = ; num[bnum] = now;
bnum++; next[bnum] = p[y]; p[y] = bnum;
v[bnum] = x; zheng[bnum] = ; kexing[bnum] = ; num[bnum] = now;
} void ss(int now)
{
int k = p[now];
while (k != -)
{
if (kexing[k])
{
kexing[k] = ; kexing[k^] = ;
ss(v[k]);
ansnum++;
ans[ansnum][] = num[k^];
ans[ansnum][] = zheng[k^];
}
k = next[k];
}
} int main()
{
scanf("%d", &n);
for (int i = ; i <= ; ++i) p[i] = -;
for (int i = ; i <= n; ++i)
{
int x, y;
scanf("%d%d", &x, &y);
du[x]++; du[y]++;
addbian(x, y, i);
}
if (n == )
{
printf("No solution\n");
return ;
}
int jnum = , start = -;
for (int i = ; i <= ; ++i)
if (du[i] % != )
{
jnum++; start = i;
}
if (jnum != && jnum != )
{
printf("No solution\n");
return ;
}
if (start == -)
for (int i = ; i <= ; ++i)
if (du[i] != ) start = i;
ss(start);
if (ansnum < n)
{
printf("No solution\n");
return ;
}
for (int i = ; i <= n; ++i)
{
printf("%d ",ans[i][]);
if (ans[i][]) printf("+\n");
else printf("-\n");
}
}
sgu 101 domino的更多相关文章
- SGU 101 Domino (输出欧拉路径)
101. Domino time limit per test: 0.25 sec. memory limit per test: 4096 KB Dominoes – game played wit ...
- SGU 101.Domino( 欧拉路径 )
求欧拉路径...直接dfs即可,时间复杂度O(N) -------------------------------------------------------------------------- ...
- sgu 101 Domino 解题报告及测试数据
101. Domino time limit per test: 0.25 sec. memory limit per test: 4096 KB 题解: 求多米诺骨牌按照一定方式放置能否使相邻的位置 ...
- SGU 101 Domino【欧拉路径】
题目链接: http://acm.sgu.ru/problem.php?contest=0&problem=101 题意: N个多米诺骨牌,每个骨牌左右两侧分别有一个0~6的整数(骨牌可以旋转 ...
- SGU 101.Domino (欧拉路)
时间限制: 0.5 sec 空间限制: 4096 KB 描述 多米诺骨牌,一种用小的方的木块或其他材料,每个都被一些点在面上标记,这些木块通常被称为骨牌.每个骨牌的面都被一条线分成两个 方形,两边 ...
- SGU 101 Domino 题解
鉴于SGU题目难度较大,AC后便给出算法并发布博文,代码则写得较满意后再补上.——icedream61 题目简述:暂略 AC人数:3609(2015年7月20日) 算法: 这题就是一笔画,最多只有7个 ...
- ACM: SGU 101 Domino- 欧拉回路-并查集
sgu 101 - Domino Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Desc ...
- SGU 101
SGU 101,郁闷,想出来算法,但是不知道是哪个地方的问题,wa在第四个test上. #include <iostream> #include <vector> #inclu ...
- Domino - SGU 101 (欧拉路径)
题目大意:这是一个多米诺骨游戏,这个游戏的规则就是一个连着一个,现在给出 N 个多米诺,每个多米诺两边都有一个编号,相邻的多米诺的编号要一致,当然多米诺是可以翻转的(翻转就加‘-’,不翻转是‘+’), ...
随机推荐
- JS幻灯片,循环播放,滚动导航,jQuery平滑旋转幻灯片
最近在帮别人改一些东西,在网上找了好久,但是没有相同的,自己改了下,拿出来分享下: 先展示下效果把: index.html 页面展示代码 <!DOCTYPE html PUBLIC " ...
- cocos2d-x 聊天输入框实现
转自:http://bbs.9ria.com/thread-216948-1-10.html 聊天输入框 (单行输入框 ,多行可自己扩展) 实现功能: 1.普通输入 2.设置输入框显示最大宽度(PT ...
- Oracle DB 执行表空间时间点恢复
• 列出在执行表空间时间点恢复(TSPITR) 时会发生的操作 • 阐释TSPITR 使用的术语的定义 • 确定适合将TSPITR 用作解决方案的情况 • 确定时间点恢复的正确目标时间 • 确定不能使 ...
- MongoDB(四)——管理架构
前面介绍MongoDB基础,在这里,我们推荐两个网站,我们可以看看,评论是相当具体:http://www.w3cschool.cc/mongodb/mongodb-tutorial.html.http ...
- TIME-WAIT和CLOSE-WAIT
系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT 2016-03-11 运维帮 来源微信订阅号:大房说 作者:大房 你遇到过TIME_WAIT的问题吗? 我相信很多都遇到过这个问题. ...
- [JavaScript]JS对select动态options操作[IE&FireFox兼容]
<select id="ddlResourceType" onchange="getvalue(this)"></select> ...
- 信号之sigsetjmp和siglongjmp函数
在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回. 但是,调用longjmp有一个问题.当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号 ...
- eclipse+ADT 进行android应用签名详解
http://jojol-zhou.iteye.com/blog/719428 1.Eclipse工程中右键工程,弹出选项中选择 android工具-生成签名应用包: 2.选择需要打包的android ...
- View绘制详解(三),扒一扒View的测量过程
所有东西都是难者不会,会者不难,Android开发中有很多小伙伴觉得自定义View和事件分发或者Binder机制等是难点,其实不然,如果静下心来花点时间把这几个技术点都研究一遍,你会发现其实这些东西都 ...
- 如何取消tableView的footer的粘滞效果
footer默认的是固定在底部的 但有时我们需要和view一起滚动 主要是在scrollViewDidScroll这个代理方法中监听滚动的状况 设置如下 - (void)scrollViewDidS ...