puzzle(0121)《一笔画》
目录
一,一笔画三定律
二,一笔画2
1,简单图
2,带二重平行边的图
3,带1个传送门的图
4,带绿线的图
4.1,基于闭环的分割
4.2,完全分割图
4.3,对称性
4.4,基于有向小闭环的消去原理
4.5,基于传送门的分割
4.6,基于邻居的出度和入度估计法(类似贪心算法)
4.7,优先级原则
4.8,基于绿线的分割
三,CCF-CSP-2015-12-4 送货
一,一笔画三定律
一笔画第一定律:对于无向连通图,如果奇点数量为0或者2,则可以一笔画,否则不能一笔画。
一笔画第二定律:对于无向连通图,如果奇点个数为2,那么2个奇点可以任选1个作为起点,其他点不能作为起点,如果奇点个数为0,那么任何一个点都可以作为起点。
一笔画第三定律:对于无向连通图,起点由第二定律决定,在一笔画的过程中,只要始终保持所有的边是连通的,最终一定能完成一笔画。
二,一笔画2
这篇文章,我想分享一下自己的经验,关于如何快速找到起点。
APK下载链接:资源分享汇总_nameofcsdn的博客-CSDN博客_上海各区gm资源汇总
规则介绍:
这个游戏是要一笔画完整个图,由于起点为给出,所以需要自己寻找。
如果一开始起点就选错了,那么无论如何都无法过关了。
这个游戏,是难度递增的,可以分成四大类。
第一种,是只有蓝线的(有的上面还有箭头),也就是简单图。
第二种,有了红线(有的上面还有箭头),红线其实就是二重平行边。
第三种,有了传送门,传送门是2个黄点组成的一对。(图中只有1个传送门,也只有2个黄点)
第四种,有了绿线,绿线都是带箭头的,而且其中一端是绿点。每次经过绿点,绿线的方向就会改变。
下面分这四种类型,分别介绍如何寻找起点。
1,简单图
简单图有2种,一种是没有奇点的:
无论是有向图还是无向图,一定是一个闭环,那么任何点都可以用作起点。
另外一种是有2个奇点的:
2个奇点必定是起点和终点。
在无向图中,任意一个做起点,另外一个做终点,都可以。
在有向图中,有的像图12一样,2个点都可以作为起点,有的像图14一样,只有1个点能作为起点。
对于有唯一起点的情况,要想找出起点,还需要下面的定理。
定理一:在有2个奇点的有向图中,除了2个奇点之外,所有的点都满足入度==出度,
而这2个奇点中,起点满足入度==出度-1,终点满足入度==出度+1(证明略~~~)
图14中这个定理的使用:
分析点3就可以发现,点3到点2之间的线的方向是2→3而不是3→2,如图。
同理,分析点4可以发现是4→2,分析点5可以发现是2→5。
那么,点2即为起点,点1即为终点。
2,带二重平行边的图
红线的意思是,这条线必须经过2次,其实也就是二重平行边,1条红边等价于2条平行的蓝边。
理解什么叫二重平行边之后,问题就可以轻松地等价转化成前面的简单图的问题了。
如图22中,点1和点2是奇点,而且点1的出度至少为2,所以点1是起点,点2是终点。
3,带1个传送门的图
定理二:
对于2个传送门的2个端点,即黄点A和B,A的入度减B的出度一定是0或者1或者是-1
如果是1,那么A是终点,如果是-1,那么B是起点。
对于A和B之外的点,如果是奇点,就一定是起点或终点,对于A和B就不一定了。
定理二的推论:
A和B的度一定相差为2或者1或者0
1,如果相差是2,那么度大的那个点既是起点,又是终点,除了A和B之外没有奇点。
2,如果相差是1,那么度大的那个点即为起点或终点,除了A和B之外恰有1个奇点,这个点也是起点或终点。
如图33,因为点1的入度至少为2,所以点1是终点,点3是起点。
3,如果相差是0,那么又有2种情况:
(1)除了A和B之外恰有2个奇点,那么这2个点就是起点和终点
(2)除了A和B之外没有奇点,那么整个图一定是闭环,任何点都可以作为起点。
4,带绿线的图
绿线本质上是一条有向边,只不过方向不好确定。
所以说,以上提到的所有内容,对于带绿线的图同样成立。对于简单的情况,用上述内容即可解决。
但是,对于大部分情况,上述内容无法得到结果,因为绿线不是无向边,必须按照绿箭头的方向走,而绿箭头的方向却又总是变,所以定量的分析效果不大。
所以接下来,我会列举一些经典的情形,来给出一些方法。实际上,这些方法也可以用到无绿线的图中,效果一样很好。
4.1,基于闭环的分割
(不一定保证对,但目前还没有出错过,而且有奇效)
把图分割成2个子图,一个图是闭环(多个闭环合起来还是闭环),另外一个图包含绿线。
让包含绿线的图尽量简洁,然后优先解决这个图,最后只要解决这个闭环就可以了。
例1:
例2:
例3:
(红线不是闭环,但是红线加闭环还是闭环)
例4:
例5:
对于图133,有2个点是奇点,但是不知道哪个是起点。
定理三:
如果一个图可以分成2个子图,这2个子图只有2个公共点(都不是黄点),而且这2个点就是起点和终点,那么这2个子图一定有1个是闭环。
根据这个定理,图133虽然有2个黄点,但是起点和终点都不是黄点,而且可以分成上下2个子图,所以上面的子图一定是闭环,所以只需要先解决下面的子图。
一眼看过去,很难看出上面的子图是闭环,不过确实是闭环。
4.2,完全分割图
随便命名的,就是指这种如果不考虑传送门的效果的话,2个部分完全分割开来的图。
如果其中有1个部分是不自相交的闭环的话,那就太简单了,起点一定在另外1个部分。
(考虑到整个图为闭环的情况,更严谨的说法应该是,起点一定可以是另外1个部分上面的点)
在另外1个部分找起点的时候,可以忽略掉传送门,这样就很简单了。
4.3,对称性
这2个图都有着比较强的对称性,但不是完全对称。
2个都是,2个奇点都可以作为起点
4.4,基于有向小闭环的消去原理
其实这个和基于闭环的分割差不多,一步步挖掘出小闭环,必须是有向的。
图109可以分成5个子图,4个有向小闭环都消去之后,就只剩1条简单的路径了。
4.5,基于传送门的分割
根据传送门,分割成若干块,每一块都相当于若干条连接2个传送门的线段。
很明显,她们是有主次之分的。
一般来说,主分区只有1个,其他都是次分区。
次分区的特点很明显,简单,无限制或者限制很少(限制主要指箭头)。
当然,还有一种特殊的情况,箭头特别多,但是全部指向同一个传送门,这也是一种很有趣的闭环。
最重要的是,次分区没有奇点,可以构成闭环。
这样看起来,每个分区都可以轻松解决掉。
主分区是一条路径,除了起点和终点之外,至少有1个点是传送门,所以主分区是由2部分构成,起点→传送门,传送门→终点。
所以完整的路径是:起点→传送门,第一个次分区,第二个次分区......最后一个次分区,传送门→终点。
4.6,基于邻居的出度和入度估计法(类似贪心算法)
我之所以总结出这样一个方法,实在是因为上面的方法对下图120几乎无效,图120实在是难的离谱。
点和边的位置关系可以分4类:
第一种,点是边的2个端点之一
第二种,点和边的2个端点都是邻居
第三种,点和边的2个端点,一个是邻居,一个不是邻居
第四种,点和边的2个端点都不是邻居
基于邻居的出度和入度估计法:只考虑和奇点形成第一种或者第三种位置关系的有向边,计算所有这样的边对奇点的入度或者出度的贡献的总和,然后比较2个奇点得到起点和终点。
首先,点1和点2是奇点,ABCD四条边都是有向边。
对于点1,只考虑ABC,对于点2,只考虑D
然后计算贡献
对于点1 A:入度+2 B:出度+1 C:出度+1 合计:贡献为0
对于点2 D:入度+2 合计:贡献为入度加2
所以,2是终点,1是起点。
注意:当2个奇点的计算值相差为2或者超过2,往往非常可信,相差为1甚至0的话就不是特别可信了。
这里面还要注意绿线的问题,如果绿线的方向可以预先确定的话,绿线也可以参与计算贡献,但是如果绿线的方向无法确定,或者特别麻烦,懒得分析这个,那绿线可以不参与计算贡献。
再看2个例子:
很明显点1和点2是起点和终点。
点1的计算值为0,点2的计算值为出度加2,所以点2为起点。
很明显点1和点2是起点和终点。
点1的计算值为0,点2的计算值为入度加1,所以点1为起点。
4.7,优先级原则
原则一,对于能够确定方向的绿线,优先干掉绿线
原则二,优先级,有向红边>有向蓝边>红边>蓝边
4.8,基于绿线的分割
有些图是由子图+绿线+子图构成的,即绿线是连接2个子图的唯一的边。
这里的子图,指的是不包含传送门或者包含2个传送门的图。
开局的时候绿箭头的方向一定就是最后通过绿线的方向,所以绿点所在的那个子图一定包含起点。
(这个子图包含绿点)
三,CCF-CSP-2015-12-4 送货
题目:
问题描述
为了增加公司收入,F公司新开设了物流业务。由于F公司在业界的良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了城市的每条街道。然而,F公司现在只安排了小明一个人负责所有街道的服务。
任务虽然繁重,但是小明有足够的信心,他拿到了城市的地图,准备研究最好的方案。城市中有n个交叉路口,m条街道连接在这些交叉路口之间,每条街道的首尾都正好连接着一个交叉路口。除开街道的首尾端点,街道不会在其他位置与其他街道相交。每个交叉路口都至少连接着一条街道,有的交叉路口可能只连接着一条或两条街道。
小明希望设计一个方案,从编号为1的交叉路口出发,每次必须沿街道去往街道另一端的路口,再从新的路口出发去往下一个路口,直到所有的街道都经过了正好一次。
输入格式
输入的第一行包含两个整数n, m,表示交叉路口的数量和街道的数量,交叉路口从1到n标号。
接下来m行,每行两个整数a, b,表示和标号为a的交叉路口和标号为b的交叉路口之间有一条街道,街道是双向的,小明可以从任意一端走向另一端。两个路口之间最多有一条街道。
输出格式
如果小明可以经过每条街道正好一次,则输出一行包含m+1个整数p 1, p 2, p 3, ..., p m +1,表示小明经过的路口的顺序,相邻两个整数之间用一个空格分隔。如果有多种方案满足条件,则输出字典序最小的一种方案,即首先保证p 1最小,p 1最小的前提下再保证p 2最小,依此类推。
如果不存在方案使得小明经过每条街道正好一次,则输出一个整数-1。
样例输入
4 5
1 2
1 3
1 4
2 4
3 4
样例输出
1 2 4 1 3 4
样例说明
城市的地图和小明的路径如下图所示。
样例输入
4 6
1 2
1 3
1 4
2 4
3 4
2 3
样例输出
-1
样例说明
城市的地图如下图所示,不存在满足条件的路径。
评测用例规模与约定
前30%的评测用例满足:1 ≤ n ≤ 10, n-1 ≤ m ≤ 20。
前50%的评测用例满足:1 ≤ n ≤ 100, n-1 ≤ m ≤ 10000。
所有评测用例满足:1 ≤ n ≤ 10000,n-1 ≤ m ≤ 100000。
代码:
#include <iostream>
#include<queue>
#include<list>
#include<stack>
#include<algorithm>
#include<stdio.h>
using namespace std;list<int>edge[10001];
int n;
stack<int>ans;int num_of_sin() //求奇点的个数,是0,2,还是大于2
{int ans = 0;for (int i = 1; i <= n && ans<=2; i++)if (edge[i].size() % 2)ans++;return ans;
}bool con() //判断是否为连通图
{int *p = new int[n + 1];for (int j = 1; j <= n; j++)p[j] = 0;queue<int>q;while (!q.empty())q.pop();p[1] = 1, q.push(1);while (!q.empty()){int k = q.front();q.pop();for (list<int>::iterator it = edge[k].begin(); it != edge[k].end(); it++)if (p[*it] == 0){p[*it] = 1;q.push(*it);}}for (int j = 1; j <= n; j++)if (p[j] == 0)return false;return true;
}bool ok() //判断能不能一笔画
{if (num_of_sin() > 2 || !con())return false;if (num_of_sin() == 0)return true;return edge[1].size() % 2;
}bool dfs(int s, int deep)
{if (edge[s].empty())return deep == 0;int e = *min_element(edge[s].begin(), edge[s].end());edge[s].remove(e), edge[e].remove(s);if (dfs(e, deep - 1)){ans.push(e);return true;}if (edge[s].empty()){edge[s].push_back(e), edge[e].push_back(s);return false;}int t = *min_element(edge[s].begin(), edge[s].end());edge[s].push_back(e), edge[e].push_back(s);e = t;edge[s].remove(e), edge[e].remove(s);if (dfs(e, deep - 1)){ans.push(e);return true;}edge[s].push_back(e), edge[e].push_back(s);return false;
}int main()
{int m, a, b, s = 1;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)edge[i].clear();for (int i = 0; i < m; i++){scanf("%d%d", &a, &b);edge[a].push_back(b), edge[b].push_back(a);}if (!ok()){cout << -1;return 0;}while (!ans.empty())ans.pop();dfs(1, m);cout << 1;while (!ans.empty()){printf(" %d", ans.top());ans.pop();}return 0;
}
puzzle(0121)《一笔画》相关推荐
- puzzle(0122)网格一笔画
目录 一,一笔画完(网格图带起点) 二,网格图不带起点 三,拾穗方块(带重复次数的网格图) 四,数字连线(带重复次数的网格图,多起点分割) 规则一 规则二 规则三 规则四 五,走出六角机关(六边形网格 ...
- 32个笔画顺序表图片_32个笔画掌握透了,练字真的不难
笔画作为硬笔书法最基础的部首,也是十分重要的一部分.建议初学者一定先要学好这些笔画.配图选自田英章老师的楷书教材. 这本教材是我上大学时候,社团统一购买的.由于都是大部分都是摹写的,我本人不喜欢摹写, ...
- 学会在Unity中创建一个Match-3益智游戏 Learn To Create a Match-3 Puzzle Game in Unity
MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:48场讲座(6h 38m) |大小解压后:2.8 G ...
- 一笔画问题【数据结构-图论】
回家路上听到2个人在说:田字怎么一笔写成,并且笔划不重复. 田 我回家想了许久,觉得无论如何走正常的途径肯定是不行的,投机取巧脑筋急转弯的我不讨论. 那么是否可以找到数学定理? 其实就是欧拉七桥问题: ...
- 汉字笔画数据_统计学原理 数据的预处理
数据审核 数据审核-原始数据(raw data) 完整性审核 应调查的单位或个体是否有遗漏 所有的调查项目或变量是否填写齐全 准确性审核 数据是否真实反映实际情况,内容是否符合实际 数据是否有错误,计 ...
- 【杭电ACM】1097 A hard puzzle
[杭电ACM]1097 A hard puzzle http://acm.hdu.edu.cn/showproblem.php?pid=1097 先用int手写了算法结果竟然wrong answer ...
- 模板 - 欧拉路、欧拉回路(一笔画问题)
整理的算法模板合集: ACM模板 目录 非递归版 普通递归版 HierholzersHierholzersHierholzers算法(输出字典序最小的答案) FleuryFleuryFleury算法 ...
- 一笔画 (25 分)
小丁最近迷恋上一个游戏,传说中的"一笔画"游戏. 那么什么是一笔画?如下图,顾名思义就是一笔可以完成的图.一笔画最基本的要求是在画图的过程中,笔不能离开纸,且笔所画过的线不能重复, ...
- pygame的字体画不出来_5毛钱的圆珠笔画的?每一幅都是大师之作,网友:为何我画不出来...
5毛钱的圆珠笔画的?每一幅都是大师之作,网友:为何我画不出来 艺术家们总是在记录这个社会,他们通过各种各样的方式来表现出他们对这个社会的热爱,而这些方式中最常见的就是绘画了,在艺术家的画笔之下,定格了 ...
最新文章
- python好学吗mooc中文网-Python全栈工程师
- Nginx 笔记与总结(15)nginx 实现反向代理 ( nginx + apache 动静分离)
- 结合传统与数字技术,构建逼真的机械设计
- 你可能对position和z-index有一些误解
- 关于编程学习的一些思考 | 欢迎投稿
- Spring Boot 2.0.0.M7 生产环境部署
- 你了解语音识别技术吗?
- iOS 关于本地持久化存储的探讨
- 4170万元人民币的“绿坝·花季护航”预装1年软件,到底值不值?
- 分盘后磁盘空间不够,用分区助手增加某个磁盘空间
- 小米6X 线刷兼救砖_解账户锁_纯净刷机包_教程
- bc547可以用8050代换吗_常用三极管代换型号
- JS特效三:LightBox(轮播图+图片弹窗)
- ES mapping
- [SpriteKit] 制作瓦片地图小游戏
- 分享最近发现的几个实用 chrome/edge 扩展和油猴脚本
- python使用openCV图像加载(转化为灰度图像)、平滑图像处理就是将每个像素的值变换为其相邻元素的平均值、可视化平滑处理之后的图像(Blurring Images)
- 每月一书(202202): 《从零开始做自媒体》
- 微信小程序抓包教程:Burpsuite版 附所需工具
- 算法:数据流中的中位数