2020中兴捧月-傅里叶-丰收祭赛题常规解法

语言:python

耗时:一阶段256*640:16s,二阶段1344*1344:600s。

复赛入围

题目要求可以概括为无向图找环。

思路:

  1. 以起点为最小点:为尽可能减少找到重复的环,可以定一个环的标准型:第一个点为环中相同部落的点中最小的,如环4A1F5B,假定部落A中的id都为数字,则这个环只可以从1为起点搜索到。根据此想法可以在搜索途中以每个部落A中的点作为起点开始搜索有限深度,找到以此点为起点的所有环,剪枝逻辑为剪去所有部落A中不大于起点的邻接点。
  2. 双向搜索:以某个点为起点的环可以通过从起点出发的两个方向找到最远点,根据这一点,要找一个长度为n的环可以将搜索深度从n变成n/2+1。代码中实现为在某个起点的搜索过程中将以某个点为终点的多条路径保存在字典中,终点的id作为键,终点相同的路径的列表作为值,然后逐一匹配组装环,之后将之前的长度为n/2+1的路径延长1,再组成长度n+2的环,重复上述步骤直到找完最长的环。
  3. 组装环:由于是无向图,可以直接对n/2+1长度的路径集合进行匹配找出所有长度n的环,能组成环的两条路径应是只有首尾id相同的。
  4. 排除重复环:根据以上策略会找到顶点相同但排列顺序不同的环,所以将找出来的环的顶点排序之后存入集合,每次找到环之后都确认一下有相同顶点集合的环是否已经被找到过,采用将环中的id重新排序的办法来区分顶点相同的环。
  5. 度小于2的点不做为起点。
  6. 做了一点优化。优化代码逻辑结构+函数内联+用for循环代替求交集。

代码:https://github.com/EatmyantisoulButterfly/2020-.git

总结:没有找到规律的菜鸡只能用用常规方法。。


题目:

在某片遥远的大陆上,居住着两个世代友好的部落,分别是部落A和部落B。他们一起耕耘劳作,互相帮助,亲如一家。久而久之,部落里的每个人都在对方部落里找到了志趣相投,互相欣赏的好朋友。有的人性格热情开朗,好朋友很多;有的人性格沉稳内敛,好朋友相对少一些。

每到秋天丰收的季节,这两个部落的人民都会聚集在一起举行盛大的“丰收祭”,来祈祷下一年的风调雨顺。今年的丰收祭马上又要举行了。为了进一步增进两个部落的友谊,也为了明年能有一个好收成,这两个部落的祭司们商量后决定:在今年的丰收祭前举办一场特别的“击鼓传花”游戏。只不过游戏中并非有人真的击鼓,并且所传递的“花”也不是真的花,而是等待在丰收祭上献上的祭品。

游戏规则如下:

  1. 两个部落的所有人都可以事先准备自己的祭品,且每个人的祭品样式都不同,每一个祭品都分别盛放在一个相对应的木托盘里;准备此祭品的人熟悉自己的祭品;
  2. 每个人可以准备的祭品数量不限;祭品的最小不可分割单位是1份;
  3. 游戏开始后,在整个游戏过程中,每个人都能且只能将祭品(包括木托盘)传递给自己在对方部落里的好朋友们,每个好友可以接收的祭品数量不限;
  4. 收到祭品的人必须在盛放此祭品的木托盘上刻上自己的名字(代表留下自己美好的祝愿),随后按照上一条规则,继续传递;
  5. 如果祭品回到最初准备此祭品的人手中,此人也在木托盘上刻上自己的名字之后,终止传递;
  6. 木托盘上不允许出现重复的人名,如果无法满足此条件,则不再继续传递该祭品;
  7. 当所有的祭品都不再传递后,游戏结束;

 

游戏开展得非常顺利。游戏结束后,祭司们将收集同时满足如下三个条件的祭品用于接下来的丰收祭活动:

  1. 此祭品回到了最初准备它的人手中;
  2. 盛放此祭品的木托盘上至少有4个名字,至多有14个名字;
  3. 如果有多个木托盘上的名字完全一样(不区分名字的排列顺序),则从其中随机选择一个木托盘所对应的祭品。

 

 

问题:

已知这两个部落里的所有人都不重名,并且部落A的人和部落B的人之间的好朋友关系以附件的csv数据表格文件给出,其中行索引代表部落A中的人,列索引代表部落B中的人,表格中的数字“1”代表他们两人是好朋友,“0”代表他们两人不是好朋友。请问:

如果以木托盘上的名字的数量对用于丰收祭的祭品分类,每一类分别最多有多少个祭品?

 

请参赛者答题:

木托盘上有4个名字的祭品最多有()个;木托盘上有6个名字的祭品最多有()个;木托盘上有8个名字的祭品最多有()个;木托盘上有10个名字的祭品最多有()个;木托盘上有12个名字的祭品最多有()个;木托盘上有14个名字的祭品最多有()个;

请在每个()中填写一个正整数答案;

你可能感兴趣的:(python,数据结构,算法,图论)