题意还算简洁明了,加上有道翻译凑过着读完了题。题意大体上是 给你 个多米诺骨牌, 给出每个骨牌两端的数字, 只有数字相同才可以推到, 比如 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的更多相关文章

  1. SGU 101 Domino (输出欧拉路径)

    101. Domino time limit per test: 0.25 sec. memory limit per test: 4096 KB Dominoes – game played wit ...

  2. SGU 101.Domino( 欧拉路径 )

    求欧拉路径...直接dfs即可,时间复杂度O(N) -------------------------------------------------------------------------- ...

  3. sgu 101 Domino 解题报告及测试数据

    101. Domino time limit per test: 0.25 sec. memory limit per test: 4096 KB 题解: 求多米诺骨牌按照一定方式放置能否使相邻的位置 ...

  4. SGU 101 Domino【欧拉路径】

    题目链接: http://acm.sgu.ru/problem.php?contest=0&problem=101 题意: N个多米诺骨牌,每个骨牌左右两侧分别有一个0~6的整数(骨牌可以旋转 ...

  5. SGU 101.Domino (欧拉路)

    时间限制: 0.5 sec 空间限制: 4096 KB 描述 多米诺骨牌,一种用小的方的木块或其他材料,每个都被一些点在面上标记,这些木块通常被称为骨牌.每个骨牌的面都被一条线分成两个   方形,两边 ...

  6. SGU 101 Domino 题解

    鉴于SGU题目难度较大,AC后便给出算法并发布博文,代码则写得较满意后再补上.——icedream61 题目简述:暂略 AC人数:3609(2015年7月20日) 算法: 这题就是一笔画,最多只有7个 ...

  7. ACM: SGU 101 Domino- 欧拉回路-并查集

    sgu 101 - Domino Time Limit:250MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u Desc ...

  8. SGU 101

    SGU 101,郁闷,想出来算法,但是不知道是哪个地方的问题,wa在第四个test上. #include <iostream> #include <vector> #inclu ...

  9. Domino - SGU 101 (欧拉路径)

    题目大意:这是一个多米诺骨游戏,这个游戏的规则就是一个连着一个,现在给出 N 个多米诺,每个多米诺两边都有一个编号,相邻的多米诺的编号要一致,当然多米诺是可以翻转的(翻转就加‘-’,不翻转是‘+’), ...

随机推荐

  1. Unity3d 使用NPOI读写Excel 遇到的问题

    开发环境:unity5.3  NPOI(.net 2.0版  http://npoi.codeplex.com/) 运行环境:PC版, 其他平台没有测试 先上效果图: 实现步骤: 1.新建一个Exce ...

  2. Custom Properties for Alert Description and Notification(PropertyBag)

    Alert Description Variables: For event Rules: EventDisplayNumber (Event ID):             $Data/Event ...

  3. 常见排序算法及其java实现

    最近学习了下java,感觉java在基本语法上与C++非常相似.作为练习,我用java实现了冒泡排序.选择排序.插入排序.基尔排序.快速排序.堆排序.计数排序.合并排序. 以下为实现代码: publi ...

  4. c++ 操作注冊表

    1.       注冊表简单介绍 注冊表是为Windows NT和Windows95中全部32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息.16位驱动在Winnt (W ...

  5. 基于新浪sae使用php生成图片发布图文微博

    1.生成图片的代码: <?php header ("Content-type: image/png"); mb_internal_encoding("UTF-8&q ...

  6. Android权限设置android.permission完整列表

    android.permission.ACCESS_CHECKIN_PROPERTIES允许读写访问"properties”表在checkin数据库中,改值可以修改上传( Allows re ...

  7. 管道技巧-while read line

    http://blog.csdn.net/hunanchenxingyu/article/details/9998089

  8. C# 墙纸更换程序

    Win7 自带的主题可以实现墙纸更换功能,同时也提供了定时更换功能. 附带效果 淡入淡出 如图 C#编写墙纸更换程序,如果使用Windows Api你会看不到那种 淡入淡出 的效果,它只会很突兀的就换 ...

  9. 学习PHP时的一些总结(五)

    mysql中启用事务的数据表类型建议使用InnoDB 利用PHP代码调用mysql中的事务过程: 1>关闭自动提交过程 $mysqli->autocommit(0); 2>执行sql ...

  10. Java设计模式06:常用设计模式之适配器模式(结构型模式)

    1. Java之适配器模式(Adapter Pattern) (1)概述:    将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起 ...