各种图论模型及其解答(转)

各种图论模型及其解答(转)

原文转自Jelline blog

http://blog.chinaunix.net/uid-9112803-id-411340.html

摘要:

本文用另一种思路重新组织《图论及其应用》相关知识。首先,用通俗化语言阐述了如何对事物间联系的问题进行图论建模;接着从现实例子出发,给出 各种典型图论模型,每种图论模型对应于图论一个重要内容;再者,介绍相关知识对上述提到的图论模型涉及的问题进行解答;最后,补充一些图论其他知识,包括 图论分支、易混概念。

符号约定:

Q(Question)表示对问题描述,M(Modeling)表示数学建模过程,A(Answer)表示原问题转化为何种图论问题。

一、引言

图论是研究点、线间关系的一门学科,属于应用数学的一部分。现实生活中,凡是涉及到事物间的关系,都可以抽象为图论模型。点表示事物,连线表示事物间的联系。整个求解过程如下:

原问题——>图论建模——>运用图论相关理论求解——>转化为原问题的解

整个过程关键在于图论建模,所谓图论建模,就是明确点表示什么,连线表示什么,原问题转化为图论中的什么问题。存在以下两种情况:

①若事物间联系是可逆的(比如双行道,朋友),则抽象成无向图

②若事物间联系是不可逆的(比如单行道,状态转化不可逆),则抽象成有向图

如果需要进一步刻画事物间的联系(比如城市间的距离),就给连线赋一个权值,从而抽象成赋值图。

综上,根据实际问题,可建模成下列图论模型的一种:无向赋权图、有向赋权图、无向非赋权图、有向非赋权图。

例1.宴会定理:任何一宴会中,一定存在两个人有相同的数量朋友

M:点表示人,连线表示当且仅当该两个人是朋友

A:问题转化为任何一个图一定存在两个顶点的度相等

二、图论模型

接下来介绍若干典型的图论模型,每种模型几乎对应于图论的一个重要内容,这些内容将在第三章进行讨论,也就给出了这些模型的解答思路。

2.1 偶图模型

凡涉及两类事物间的联系(即只考虑两类事物间的联系,而不考虑同类事物间的联系),均可抽象成偶图模型。作图时,将两类事物分成两行或者两列。这类模型通常被包含在后续的模型中,但因许多现实问题可抽象成该模型,所以单列出来讨论。

(1) 仓库与销售间

M:点代表仓库或销售点,连线代表仓库与销售店间的关联

(2) 上课安排问题

Q:学校有6位教师将开设6门课程。六位教师的代号是Xi(i=1,2,3,4,5,6),六门课程代号是Yi (i=1,2,3,4,5,6)。已知,教师X1能够胜任课程Y2和Y3;教师X2能够胜任课程Y4和Y5;教师X3能够胜任课程Y2;教师X4能够胜任课程Y6和Y3;教师Y5能够胜任课程Y1和Y6;教师X6能够胜任课程Y5和Y6。

M:点表示教师或者课程,连线表示当且仅当该教师能胜任该课程

2.2 最短路模型

凡涉及到最小状态转换问题,均可转化为最短路模型。点表示允许的状态,连线表示状态的转换(可逆与不可逆分别对应于无向图、有向图)。

(1) 最短航线

M:点表示城市,连线表示当且仅当两城市有直达航线,并在该线上注明两城市的距离,即权值

A:问题转化为求两点间的最短路径

(2) 状态转换

Q:某两人有一只8升的酒壶装满了酒,还有两只空壶,分别为5升和3升。求最少的操作次数能均分酒。

M:设x1,x2,x3分别表示8,5,3升酒壶中的酒量,则

点表示组合(x1,x2,x3) ,连线表示当且仅当可通过倒酒的方式相互变换

A:问题转化为在该图中求点(8,0,0)到点(4,4,0)的一条最短路

(3) 狼羊菜渡河

Q:在一河岸有狼,羊和卷心菜。摆渡人要将它们渡过河去,由于船太小,每次只能载一样东西。由于狼羊,羊卷心菜不能单独相处。问摆渡人至少要多少次才能将其渡过河?

M:但是以下组合不能允许出现:狼羊菜,羊菜,狼羊,人,人狼,人菜,共6种。岸上只能允许出现10种组合:人狼羊菜,人狼羊,人狼菜,人羊,空,菜,羊,狼,狼菜,人羊菜。

点表示可允许的组合,连线当且仅当两种情况可用载人(或加一物)的渡船相互转变。

A:问题转化为求由顶点“人狼羊菜”到顶点“空”的一条最短路。

2.3 最小生成树模型

道路铺设

Q:道路铺设,使得任意两个地方均可达,并且费用最小

M:点表示工厂(假设是工厂),任意两点连线,并标出铺设需要的费用

A:问题转化为求该图的最小生成树

2.4 欧拉图模型

通俗地讲,G是欧拉图当且仅当G存在经过每条边恰好一次,并且回到起始点的迹。

(1) 哥尼斯堡七桥问题

Q:能否从一点出发,走遍7座桥,且通过每座桥恰好一次,最后仍回到起始地点

M:点表示陆地,连线表示桥

A:问题转化为G是否存在E图

(2) 中国邮递员问题

Q:邮递员必须走过他投递范围内的每一条街道至少一次,选择一条尽可能短的路线

M:点表示路口,连线表示当且仅当两路口有直达街道

A:若G是E图,通过Fleury算法构造Euler环游,即为所求。否则,按一定规则添加重复边,再用Fleury算法构造Euler环游。

2.5 哈密尔顿圈模型

(1) 旅行售货员问题——TSP

一售货员要到若干城市去售货,每座城市只经历一次,问如何安排行走路线,使其行走的总路程最短。

例子:

Q:一电脑代理商要从她所在城市出发,乘飞机去六个城市,然后回到出发点,如果要求每个城市只经历一次,能否办到?给出行走方案。

M:点表示城市,连线表示两城市有直达航线

A:该图是否存在H圈

(2) 圆桌会议座位安排

Q:若干人围圆周开会,每个人会不同的语言,如何安排座位,使得每个人能够和他身边的交流

M:点表示人,连线表示当且仅当两个人能交流,即至少会同一种语言。(可能你一下子想到的偶图模型,的确该问题可以抽象成偶图模型,但很难转化为图论问题)

A:给出该图的一个H圈

2.6 匹配模型

(1) 旅游座位安排

Q:有一个旅行团要组织一批人去旅游,其中一些人是朋友他们要乘坐公共汽车去,而车上的位子是成对的。因此为了让大家旅途更愉快,旅行团负责人需要将成对的朋友安排在一起。给出一种安排方案。

M:点表示旅行团的人,连线表示当且仅当两人是朋友

A:求该图的最大匹配

(2) 研究生找工作

Q:学生能找到理想工作吗?

M:点表示研究生或者工作,连线表示当且仅当学生申请了该工作

A:问题转化为求饱和每个顶点的一个匹配,即完美匹配

(3) 最优分派问题

M:点表示工作或者人员,构造完全偶图,边的权值表示该工人做此份工作的效率

A:问题转化为求该图的最优匹配

2.7 平面图模型

平面模型可以这样理解,交通网络,使得不交叉,且无需修高架桥、隧道(这里的隧道显然跟山洞不同)

(1) 电路板设计问题

Q: 连接电路元件间的导线间不能交叉。否则,当绝缘层破损时,会出现短路故障。

M;点表示电路元器件,连线表示元器件间的连接

A;该图是否可平面

(2) 景区空调管道的设计

M:点表示景区,连线表示当且仅当两景点间要铺设空调管道

A:能否把上图画在平面上,使得边不会相互交叉?

(3) 3间房子和3种设施问题

Q:要求把3种公用设施(煤气,水和电)分别用煤气管道、水管和电线连接到3间房子里,要求任何一根线或管道不与另外的线或管道相交,能否办到?

M:点表示公用设施或者房子,连线表示该类公用设施连接到该房子

A:抽象出来的图是否可平面嵌入

2.8 着色模型

点着色问题对应于顶点集合的一种划分方式,对应于分类问题。边着色对应于边集合的一种划分方式,也对应于分类问题。区分点着色模型和边着色模型,主要在于抽象出来的模型,是相邻的顶点还是相邻的边不能着同一种颜色。

(1) 点着色模型

① 考试时间安排

Q:使得学生们不会有相互冲突的考试,最小安排数

M:点表示待考的课程,连线表示至少有一个学生同时选择这两门课

A:问题转化为求该图的点色数(把互不冲突的课程、考试安排在同一个时间段完成)

② 课程安排问题

Q: 学生选择课程中,使得学生选课不会发生冲突,如何制订一张课时数尽可能小少的课表

M:点表示课程,连线表示当且仅当有某个学生同时选了这两门课程

A:问题转化为求该图的点色数

③ 交通灯的相位设置问题

Q:为了(最终)让所有的车辆都能够安全通过路口,对于交通灯来说,所需要的相位的最小数是多少

M:点表示车道,连线当且仅当两个车道上的车不能同时安全地进入路口

A:问题转化为求该图的点色数

(2)边着色模型

① 排课表问题

Q:设有m位教师,n个班级,其中教师xi要给班级yj上pij节课。求如何在最少节次排完所有课。

M:令X={x1,x2,…,xm}, Y={y1,y2,…,yn},xi与yj间连pij条边,得偶图G=(X, Y)。

A:问题转化为求该图的边着色数

(2) 比赛安排问题

Q:最少天完成比赛

M:点表示参赛人,连线当且仅当两人有比赛

A:问题转化为求一种最优边着色,即用最少色数进行正常边着色

2.9 覆盖模型

覆盖模型,对应于控制问题,通俗地讲点覆盖对应于用最少的点来控制所有边(即任一边至少有一个顶点在点独立集中),边覆盖对应于用最少的边控制所有的点。均对应于控制问题。

(1) 哨站设计

Q:城市设置哨岗,使得哨兵能监管所有街道的最少哨岗数

M:点表示交叉口,连线表示存在直达街道

A:问题转化为求该图的点覆盖

2.10 强连通性定向图模型

(1) 城市交通网设计问题

Q:一座城市为某种需要,要把所有街道改为单行道,使得人们在任意两个位置都可以相互到达。如何设计单行道方向

M:顶点表示街道交叉口,连线当且仅当存在直达街道

A:问题等价于在模型图中给出其强连通定向

(2) 竞赛图

M:循环比赛的结果可以用所谓的“竞赛图”来表示。u队战胜了v队,则由点u向v画一条有向边。显然,“竞赛图”是完全图的一种定向图。

三、模型求解

现针对上述的模型给出求解过程,每个模型几乎对应于图论的一个主要内容。

3.1 偶图模型

正如上文所说,偶图模型只是建模方式,并没有与直接问题关联起来。

3.2 最短路算法

(1) Dantjig算法——顶点标号法

在已选定的集合A的临近点集合B(不包含A集合的点),选择符合条件(选择的点不会构成回路,边权值最小)的点加入集合A。迭代,直到终点出现在集合A中。
3.3最小生成树算法
(1) Kruskal(克鲁斯克尔)算法

从G中的最小边开始,进行避圈式扩张。从符合扩展边(新加入的边不会构成回路)选择权值最小的边进行扩展。

(2) 管梅谷的破圈法

不断破圈(从赋权图G的任意圈开始,去掉该圈中权值最大的一条边,称为破圈),直到G中没有圈为止,最后剩下的G的子图为G的最小生成树。
(3)  Prim算法
对于连通赋权图G的任意一个顶点u,选择与点u关联的且权值最小的边作为最小生成树的第一条边e1。在接下来的边e2,e3,…,en-1 ,在与一条已经选取的边只有一个公共端点的的所有边中,选取权值最小的边。

3.4 Euler环游

(1) Euler环游判定

连通图G是Euler图 <==> G的每个顶点的度为偶数

连通图G有Euler迹 <==> G最多有两个奇点
(1) 构造欧拉环游(Fleury算法)
该算法解决了在欧拉图中求出一条具体欧拉环游的方法。方法是尽可能避割边行走。
(2) 最优环游算法(中国邮路问题)
若G是Euler图,则G的任何环游都是最优环游(最优环游是指在具有非负权的赋权连通图中找出一条最小权的环游)。

若G不是Euler图,则G的任何环游,通过某些边不止一次,通过以下方法求

添加重复边(其一,每条边最多重复一次,得到一个Euler多重图;其二,在该多重图的每一个圈上,如果重复经过的边数目超过圈长度的一半,则交换重复边与不重复边),而后Fleury算法求得。
3.5 Hamilton图

(1) H图判定

H图判定至今没有平凡的充要条件,不过可以通过如下定理辅助判断。

必要条件

G是H图 ==> 对于V的每个非空真子集S,均有ω(G-S)≤|S|,即若去k个点,得到连通分支数比k大,则不是H图(逆否命题)。(显然有割点的图不是H图)

充分条件

① 设G是n(n≥)阶简单图,δ≥n/2  ==> G是H图

② G是简单图,对于任意不相邻的顶点,满足d(u)+d(v)≥n,G是H图 <==> G+uv是H图

③ G是H图 <==> G的闭包是H图(若G的闭包是完全图,则G是H图。但一个图的闭包不一定是H图)

闭包构造过程:将度数之和≥图的顶点个数的非邻接顶点对递归连接起来,直到不再有这样的顶点对存在。

(2) 最优H圈

在一个赋权完全图中,找出一个有最小权的H图,称这个圈为最优H圈。目前没有有效算法,但可以通过如下近似算法求得近似值:

首先求出一个H圈,通过替换边不断改善上界。通过求最小生成树获得其下界。

3.6 匹配模型

(1)匹配判定

①最大匹配判定:

G的匹配M是最大匹配 <==> G不包含M可扩充路

② 偶图匹配判定

设G为具有二分类(X,Y)的偶图,对于X的每个子集S ,G包含饱和X的每个顶点的匹配 <==> |N(S)|≥|S|

G是k正则偶图 ==> G有完美匹配

在偶图中,最大匹配的边数等于最小覆盖的顶点数

③ 完美匹配判定

G有完美匹配 <==> 对于V的每个非空真子集S,奇分支数ο(G-S)≤|S|

每个没有割边的3正则图都有完美匹配

G有完美匹配 <==> G有1因子 (图的一个1因子的边集等价于图的一个完美匹配)

④1-因子分解

完全图K2n是1-可因子化 (除2n外,其余的每个数按箭头方向移动一个位置,在每个位置,同一行的两点邻接就得到一个1因子)

任一正则偶图是1-可因子化(不断减去完美匹配的方式求得所有1因子)

任一个具有H圈的3正则图是1-可因子化 (一个偶数个顶点的H圈可以分解为两个1-因子的并)

若3正则图有割边,则不可1-因子分解

(2)匈牙利算法——寻找偶图的最大匹配

从任一匹配M开始,若M饱和X中的每一个顶点,则M即为所求。否则,从在X在找一个非饱和点u,通过构造扎根于u的M交错树来寻找一条可扩路。交换边,得到一个更大的匹配。
(3)最优匹配(最优分派问题)

最优匹配即在赋权完全偶图中寻找一个具有最大权的完美匹配。可以通过Kuhn-Munkres最优匹配算法进行求解,该算法采用顶点标号修改策略。

3.7 平面性模型

(1)平面性判定

① 对于简单图G=(n, m),如果m>3n-6,则G是非可平面的;
② 对于连通图G=(n, m),如果每个面次数至少为l≥3,且m>(n-2)l/(l-2),则G是非可平面
③ G是可平面的 <==> G不含有与K5或K3,3同胚的子图 (库拉托斯基定理)
④ G是可平面的 <==> G不含有能够收缩成K5或K3,3的子图 (瓦格纳定理)
⑤ 通过平面性算法判定

⑥ 观察法判断,试图通过移动边,判断是否可平面

(2) 平面性算法(DMP算法)

3.8 着色模型

(1) 求点色数

① 任意的图G,均有χ≤Δ+1

② G是简单连通图,且G既不是完全图也不是奇圈,则χ≤Δ

③ G是非空简单图,则χ≤Δ2+1 (找出所有顶点度≥其相邻的顶点度 的顶点,在余下的顶点中找最大度的点,即为次大度,不等同于第二大度)

④ G是非空简单图,若G中度数最大的点互不相邻,则χ≤Δ

⑤ 对任意的平面图,均有χ≤5

⑥ 通过色多项式求得,即最小k使得Pk(G)不等于0

    上面的各种方法都很繁琐,仅给出了上界。在实际求解过程中,可以求得Δ2+1作为上界,即次大度加1。通过观察是原图是否存在Kn的子图,若存在,则下界为n。例如,若原图存在K3即三角形,则点色数至少为3。

(2) 求边色数

① G是简单图,则χ’=Δ或Δ+1

② G是偶图,则χ’=Δ

③ G是简单图,若n=2k+1且m>kΔ,则χ’=Δ+1

④ G是奇阶Δ正则简单图,则χ’=Δ+1

⑤ 设无环图G中边的最大重数为μ,则χ’=Δ+μ

(3) 着色算法

对色集标号,每次给顶点着符合条件(相邻的顶点不能着相同颜色)的最小颜色数。该算法只能保证最多用Δ+1种颜色给一个图正常着色,但不能保证使用的颜色数一定是最少。

(4) 着色计数(求色多项式)

缩边、加边递推法

① G为n阶空图,则 Pk(G)=kn

② Pk(Kn)=k(k-1)(k-2)…(k-n+1)

③ 若d(u)=1,则 Pk(G)=(k-1)  Pk(G-u)

④ 加边递推法Pk(G-e) =  Pk(G)+  Pk(G.e)

减边递推法Pk(G)= Pk(G-e)- Pk(G.e)

理想子图法

理想子图法改进
3.9覆盖模型

(1)点覆盖

一个图的点独立集(简称独立集)是指图中一些互不相邻的点构成的点子集。含点数最多的独立集称最大独立集,最大独立集所含的顶点数称为G的独立数,记为α(G),简记为α

G的一个覆盖是指G的一个顶点子集K,使得G的每条边都至少有一个端点属于K。G的最小覆盖的点数称G的覆盖数,记为β(G),简记为β

(2) 边覆盖

G的最大匹配的边数称为G的边独立数,记为α’(G),简记为α’。

设L是G的一个边子集

G的一个边覆盖是指G的一个边子集L,使得G的每个点均为L中某条边的端点。G的最小覆盖的边数称G的边覆盖数,记为β’(G),简记为β’

(3) 点覆盖与边覆盖关系

① 对任意n阶图G,均有α+β=n

② 对任意n阶图G,且δ(G)>0均有α’+β’=n

③ G是δ(G)>0的偶图,则α=β’

3.10 强连通定向算法
(1) 存在性问题
定理3( 罗宾斯,1939) 非平凡连通图G具有强连通定向<==> G是2边连通的。
(2) 强连通定向算法
从已标号集合L中选择其与未标号集合U有邻点的最高标号的点v,扩展该点u,并标点u为点v标号值加1。对所有未赋方向的边,由标号值大的顶点指向标号值小的顶点

3.11 点边面关系运算

① 握手定理:图G= (V, E)中所有顶点的度的和等于边数m的2倍

② 设T是(n, m)树,则:n=m-1

③ 设G=(n,m)是平面图,则∑deg(f) = 2m

④ 平面图欧拉公式:设G=(n,m)是连通平面图,φ是G的面数,则n-m+φ=2

四、图论分支

4.1 网络图论

网络图论又称为网络拓扑学,用图的理论,对电路的结构及其连接性质进行分析和研究。

4.2 极值图论

主要研究与图相关的极大极小问题。比如最短路径、最小生成树、最大匹配、最小覆盖、最大流等问题。更多信息,请参考维基百科Extremal Graph Theory

4.3 代数图论

用代数方法研究图论问题。更多信息,请参考维基百科Algebraic Graph Theory

4.4 拓扑图论

直接看英文吧,It studies the embedding of graphs in surfaces, spatial embeddings of graphs, and graphs as topological spaces.It also studies immersions of graphs.更多信息,请参考维基百科Topological Graph Theory

4.5 随机图论

研究以某种随机方式产生点数、边数以及边的图(英文原文:A random graph is a graph in which properties such as the number of graph vertices, graph edges, and connections between them are determined in some random way.)。更多信息,请参考维基百科Random Graph

4.6 结构图论

结构图论的核心是哈密顿问题[3]。

五、几组易混概念

5.1 图论与拓扑学

图论以前是作为拓扑学一章来讲解,现在已经发展为独立的学科。百度百科词条拓扑学,说拓扑学是近代发展起来的一个研究连续性现象的数学分支。很费解对吧,看新浪爱问知识人一回答,说“拓扑学”主要研究的是出于数学分析的需要而产生的一些几何问题。发展至今,拓扑学主要研究拓扑空间在拓扑变换下的不变性质和不变量。 维基百科词条图论,说图论的研究对象相当于一维的拓扑学。

5.2 途径、迹、路

5.3 欧拉闭迹 欧拉环游 欧拉回路

5.4 H路 H圈 H图

注:这几个,等再看一遍书后再总结。

六、进一步阅读

老师PPT给出如下参考文献,我们用的是研究生教材(张先迪,李正良.图论及其应用[M].北京:高等教育出版社.2005.2),感觉该教材主要是抄[1]的,难怪不是著而是主编。我看过[2]的,比较浅显易懂,而且给出很多人物背景介绍,读起来比较有意思。[3]我们老师也推荐比较多。

[1]美,帮迪《图论及其应用》

[2]美,Gary Chartrand《图论导引》,人民邮电出版社,2007

[3]Bela Bollobas,《现代图论》,科学出版社,2001 中国科学院研究生教学丛书

[4]美,Fred Buckley《图论简明教程》,清华大学出版社,2005  李慧霸 王风芹译

[5] 李尉萱,《图论》,湖南科学技术出版社,1979

[6] 美,Douglas B.West《图论导引》,机械工业出版社,2007 李建中,骆吉洲译

[7] 杨洪,《图论常用算法选编》,中国铁道出版社,1988

[8] 陈树柏,《网络图论及其应用》,科学出版社,1982

[9] Chris Godsil,Gordon Royle 《Algebraic Graph Theory》,世界图书出版公司北京公司,2004

[10] 王朝瑞,《图论》,高等教育出版社,1983

20190512

20190512
普及
T1
分成三个情况。
1.n%7==0 ans=n/7*2;
2.n%7==1 ans=n/7*2+1;
3.n%7>=2 ans=n/7*2+2;
T2
看错题,就没分了。
从a[2*n-1]和a[2*n]开始,到a[1]和a[2]结束,有两种情况。
1.两者相同——不做任何处理。
2.两者不相同。
寻找与a[2*i]相等的数的位置,从这个位置开始,2*i-1结束,把后面一个数的值赋给它。

提高
T1
首先可以看出等腰直角三角形是最优解。
伪·证法如下。
(图中B是要被包含的点。)


如图2,三角形OE'D'包含点B并且B在E'D'上,且E'O=D'O。
因为∠D'OE'=90°,E'O=D'O
所以∠OE'D'=(180°-∠D'OE')/2=45°
因为∠BCE'=90°
所以∠CBE'=180°-∠BC'E'-∠OE'D'=45°
所以∠OE'D'=∠CBE'=45°
所以BC=CE'
所以OE'=OC+CE'=OC+BC。
又因为OE>OC+BC。
所以OE'<OE
即等腰直角三角形是最优解。

然后所求边长即X+Y,用等腰就可以证,不想证了。

T2
这题我系统内部错误。
如果只有1或只有2就直接输出。
素数中唯一的一个偶数是2,先输出一个2.
下一个是3,即2+1,所以输出一个1.
剩下的先把剩下的2全部输出,再把剩下的1全部输出。
至于为什么,我也不知道。

5.12

...
1
周日下午的泉州市的比赛,再次考的很烂。。。

T1
Ctrl+A 真是个好东西
T2

2 2 交换不是什么好东西。。。。。。。。。。。。。。 不知道为什么这东西让我想到冒泡????????

枚举所有奇数位,如果不匹配,那么就找到匹配的那个数,用i-j-1次交换

T2,T3

不会

 

2019/5/12

1.第一题是个直角三角形,通过对题意解读可以发现,在此三角形是一个等腰直角三角形时圈定的范围最大且不会增大输出。

所以可以for循环点的坐标,储存x+y的最大值,然后输出。水题。

2.第二题是关于质数的,除2外,其他质数都是奇数,所以,先输出2,1,然后按先把2输出完再把1输出完打代码,可以得出答案,90分错误出在没有特判全是2或全是1的情况。

3.不会,过

4.不会,过

比赛

1:直角三角形:

只要推出等腰直角三角形就可以,不用去求直线方程。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<bits/stdc++.h>
using namespace std;
long long  Max,n,x,y;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        if(x+y>Max) Max=x+y;
    }  
    cout<<Max; 
    return 0;
}

2:只要知道除2以外质数都是奇数,然后保证输出最多奇数就行:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<cstdio>
using namespace std;
int n,b[5],d;
int main()
{
    freopen("prime.in","r",stdin);
    freopen("prime.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>d;
        b[d]++;
    }
    if(b[1]%2==0)
    {
        if(b[1]==2&&b[2]!=0)
        {
            cout<<2<<" ";
            cout<<1<<" ";
            for(int i=1;i<b[2];i++)cout<<2<<" ";
            cout<<1<<" ";
        }
        else
        {
            for(int i=1;i<b[1];i++)cout<<1<<" ";
            for(int i=1;i<=b[2];i++)cout<<2<<" ";
            if(b[1]!=0)cout<<1<<endl;
        }
    }
    if(b[1]%2==1)
    {
        if(b[1]==1&&b[2]!=0)
        {
            cout<<2<<" ";
            cout<<1<<" ";
            for(int i=1;i<b[2];i++)cout<<2<<" ";
        }
        else
        {
            for(int i=1;i<=b[1];i++)cout<<1<<" ";
            for(int i=1;i<=b[2];i++)cout<<2<<" ";
            cout<<endl;
        }
    }
    return 0;
}

3001比赛352

2019/5/11

1.比赛第一题

哇哦,我把输入写在文件读写之前了,该一百的写成0分。蔡

2.比赛第二题

emmmmm因为用数组做所以空间超限,然后我就删了数组一个零.....话说3000题库的回文测试很水,就我这代码交上去都能ac。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<bits/stdc++.h>
using namespace std;
int w[10000000],a,b,chang,i;
void huiwen(int x)
{
    int newed,n;
    i=x;
    newed=0;
    n=x;
    do
    {
        newed=newed*10+x%10;
        x/=10;
    }while(x>0);
    if(n==newed)w[i]=1;
}
int main()
{
    freopen("pprime.in","r",stdin);
    freopen("pprime.out","w",stdout);
    cin>>a>>b;
    for(i=a;i<=b;i++)huiwen(i);
    for(i=2;i*i<=b;i++)
    {
        for(int j=2;j*i<=b;j++)
        w[i*j]=0;
    }
    for(i=a;i<=b;i++)
    {
        if(w[i]==1)cout<<i<<endl;
    }
   return 0;
}

附上60分代码,现在改到了90.....

3.联合权值

暴力打了60分,时间超限,现在不会改....


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>
using namespace std;
int n,a[200005],b[200005],c[200005],Max,now;
long long sum;
int main()
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n-1;i++)cin>>a[i]>>b[i];
    for(int i=1;i<=n;i++)cin>>c[i];
    for(int i=1;i<=n-1;i++)
    {
        for(int j=1;j<=n-1;j++)
        {
            if(i==j)continue;
            if(i!=j)
            {
                if(a[i]==a[j])
                {
                    now=(c[b[i]]%10007)*(c[b[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(a[i]==b[j])
                {
                    now=(c[b[i]]%10007)*(c[a[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(b[i]==a[j])
                {
                    now=(c[a[i]]%10007)*(c[b[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(b[i]==b[j])
                {
                    now=(c[a[i]]%10007)*(c[a[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
            }
        }
    }
    cout<<Max<<" "<<sum%10007<<endl;
    return 0;
}

看来还是不够暴力,不然怎么会wa。

话说我比赛时输出打错了,信息竞赛不需要视力。蔡*2.

4.邪道打法不写了。

待在学府Last day

今天主要是比赛,尽然败在小学奥数,真是失败。

1:素数统计:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<bits/stdc++.h>
using namespace std;
int pan[1000005],zhi[1000005],tot,ans;、、数组注意不要开大,会爆空间。
int main()
{
    freopen("prime.in","r",stdin);
    freopen("prime.out","w",stdout);
    int i,m,n,j;
    scanf("%d%d",&m,&n);
    for(i=2;i<=n;i++)
    {
        if(!pan[i]) zhi[tot++]=i;
        for(j=0;j<=tot;j++)
        {
            if(i*zhi[j]>n) break;
            pan[i*zhi[j]]=1;
            if(i%zhi[j]==0) break;
        }
    }
    for(i=0;i<tot;i++)
    {
        if(zhi[i]>=m) ans++;
    }
    cout<<ans;
    return 0;
}

2:质数回文:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>

using namespace std;

int a,b,ch;
char ans[10],c[10],d[10];
set<int> s;

inline void strToint(char str[],int &num,int len)
{
    num=0;
    for(int i=0;i<len;i++)
        num*=10,num+=str[i]-'0';
}

inline bool isprime(int x)
{
    if(x==2||x==3)
        return 1;
    else if(x<2)
        return 0;
    for(int i=2;i*i<=x;i++)
        if(!(x%i))
            return 0;
    return 1;
}

void check(int len)
{
    for(int i=len-1;i>len/2;i--)
        ans[i]=ans[len-1-i];
    strToint(ans,ch,len);
    if(isprime(ch))
        s.insert(ch);
    return;
}

void dfs(int len,int stp)
{
    if(stp>len/2)
        check(len);
    else
        for(int i=0;i<=9;i++)
            if(stp==0&&i==0)
                continue;
            else
            {
                ans[stp]=i+'0';
                dfs(len,stp+1);
            }
    return;
}

int main()
{
    freopen("pprime.in","r",stdin);
    freopen("pprime.out","w",stdout);
    s.insert(2);
    s.insert(3);
    s.insert(5);
    s.insert(7);
    s.insert(11);
    cin>>c>>d;
    strToint(c,a,strlen(c));
    strToint(d,b,strlen(d));
    for(int i=(int)strlen(c);i<=(int)strlen(d);i++)
        if(!(i&1)||i==1||i==2);
        else
            dfs(i,0);
    for(set<int>::iterator i=s.begin();i!=s.end();i++)
        if(*i>=a&&*i<=b)
            cout<<*i<<endl;
    return 0;
}//还是有点不足······

3:联合权值:额,还不会打,有60分暴力


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>
using namespace std;
int n,a[200005],b[200005],c[200005],Max,now;
long long sum;
int main()
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n-1;i++)cin>>a[i]>>b[i];
    for(int i=1;i<=n;i++)cin>>c[i];
    for(int i=1;i<=n-1;i++)
    {
        for(int j=1;j<=n-1;j++)
        {
            if(i==j)continue;
            if(i!=j)
            {
                if(a[i]==a[j])
                {
                    now=(c[b[i]]%10007)*(c[b[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(a[i]==b[j])
                {
                    now=(c[b[i]]%10007)*(c[a[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(b[i]==a[j])
                {
                    now=(c[a[i]]%10007)*(c[b[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
                if(b[i]==b[j])
                {
                    now=(c[a[i]]%10007)*(c[a[j]]%10007);
                    sum+=now;
                    if(now>Max)Max=now;
                }
            }
        }
    }
    cout<<Max<<" "<<sum%10007<<endl;
    return 0;
}

4:小凯的疑惑:(小学奥数emmm)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <cstdio>
using namespace std;

int main(void) {
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
   
    long long a,b;
    scanf("%lld%lld",&a,&b);
    printf("%lld",a*b-a-b);
   
    fclose(stdin);
    fclose(stdout);
}