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 个多米诺,每个多米诺两边都有一个编号,相邻的多米诺的编号要一致,当然多米诺是可以翻转的(翻转就加‘-’,不翻转是‘+’), ...
随机推荐
- 使用ttXactAdmin、ttSQLCmdCacheInfo、ttSQLCmdQueryPlan获取SQL相关具体信息[TimesTen运维]
使用ttXactAdmin.ttSQLCmdCacheInfo.ttSQLCmdQueryPlan获取SQL相关具体信息,适合于tt11以上版本号. $ ttversion TimesTen Rele ...
- Android 设置横屏或竖屏
方法一:在AndroidManifest.xml中配置 如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的AndroidManifest.xml中找到你所指定的activity中加上androi ...
- [AngularJS] Taking control of your templates using $templateCache
Using $templateCache for quickly retrieval from the cache after first time used. $templateCache main ...
- 标准I/O库之流和FILE对象
对于标准I/O库,它们的操作是围绕流(stream)进行的.当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联. 对于ASCII字符集,一个字符用一个字节表示.对于国际字符集,一个字 ...
- SOAP 及其安全控制--转载
原文地址:http://my.oschina.net/huangyong/blog/287791 目录[-] 1. 基于用户令牌的身份认证 2. 基于数字签名的身份认证 3. SOAP 消息的加密与解 ...
- Upgrade Guide
Upgrade Guide This guide will point out the key points to be aware of when upgrading to version 3. A ...
- Android版本控制系统及其间的差异
一.何谓版本控制 它是一种软件工程籍以在开发的过程中,确保由不同人所编辑的同一档案都得到更新,它透过文档控制记录程序各个模块的改动,并为每次改动编上序号,并且编辑错误之后还可以回溯到以前的版本 二.可 ...
- Js 替代
替代全部:.replace(/#/g,"/") 替代第一个:.replace("#","/") var regS = new RegE ...
- LeetCode里有特色的问题存档
002* Median of Two Sorted Arrays There are two sorted arrays A and B of size m and n respectively. F ...
- JS获取网页宽高方法集合
JS获取网页宽高等方法的集合:document.body.clientWidth - 网页可见区域宽document.body.clientHeight - 网页可见区域高 document.body ...