最近抱着试水的心理参加了2020中兴捧月算法大赛傅里叶派赛题。从4.19号由旁观者转变为参赛者,到5.8号提交完成最后的文档和代码,前后算起来也有20天了。虽然自己比较菜,但毕竟是第一次参加这种比较正式的程序算法类竞赛,自己也学到了一些东西,所以还是写点东西纪念一下吧,留待日后回首。当然这也是第一次在CSDN写博客,一下解锁两个第一次,想想心里也是有点小激动。

2020中兴捧月算法赛道傅里叶派赛题菜鸡回顾

  • 0.原始赛题描述
  • 1.赛题分析与算法建立
    • 1.1问题重述
    • 1.2问题抽象
    • 1.3算法建立
  • 2.程序源码
  • 3.参考博客

0.原始赛题描述

完整赛题直接复制进来吧,怕以后忘记到底做了一道什么题(手动笑哭表情)。
情景描述:
在某片遥远的大陆上,居住着两个世代友好的部落,分别是部落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个名字的祭品最多有()个;

1.赛题分析与算法建立

1.1问题重述

本题要求祭品在A、B两部落的朋友间互相传递,祭品传递过程中除祭品发起人外,其他人不能重复接收该祭品,祭品再次回到祭品发起人手中时该祭品传递结束。
求经手4人,6人,8人,10人,12人,14人(含祭品发起人)的祭品分别最多能有多少个,对于经手人员相同,只是传递顺序不同的祭品,均算作1个有效祭品。

1.2问题抽象

如果把A、B部落的每个成员都看成一个节点,则A、B部落的朋友关系,可以理解为A类节点和B类节点的连接情况,A类节点内部、B类节点内部不存在连接情况,祭品只能在有连接情况的节点间传递。以经手14个人的祭品为例,可以理解为连接了14个节点的环路。对应1.1中的问题重述,环路连接过程中,除起点外,其他节点不允许重复经过,这种环路称为简单环路,之后描述的环路不做特别说明均指简单环路(图的概念都是参加这个比赛才学到的,后面附上几个参考博客链接)。经手14人的祭品最多能有多少个,则可理解为不同的14节点环路最多能有多少个,对于经过节点相同,只是连接顺序不同的环路均算作是1个有效环路。
假设A,B部落成员节点分别有M个和N个,对应CSV数据表格的行数与列数,为它们统一编号:A部落成员节点ID为0~~(M-1),B部落成员节点ID为M~~(M+N-1)。则根据CSV文件可以得到这些节点间的连接情况,进而构建得到一张无向图。问题抽象为根据给定无向图,求其中节点长度为4,6,8,10,12,14的环路分别有多少。

1.3算法建立

根据前述分析,本题抽象为根据给定无向图,求其中节点长度为4,6,8,10,12,14的环路分别有多少。
建立具体算法前,几点为了提高搜索环路效率的思考。
a.由于寻找的是环路,环路中的每个节点都可以作为起点,为此设环路的起点都从A类节点开始,对应节点ID为0~~(M-1)。因此依次从编号为0~~(M-1)的节点出发,遍历寻找节点长度为4,6,8,10,12,14的环路分别有多少。
b.直接进行环路的遍历寻找,当搜索的环路较长时,如12、14环,会导致搜索的速度较慢,为此采用先搜索单向路径再进行组合拼接的方式进行环路的间接遍历寻找(大佬们在群里提供的思路)。如14节点环路,可以先遍历搜索全部的8节点单向路径,如果其中2条单向路径起止点相同,且中途没有重合点,那么这2条路径可以组合拼接成1条14节点环路,这样可以从一定程度上提高搜索长节点环路的速度。
c.假设从i号节点出发,完成了全部的4,6,8,10,12,14节点环路的遍历寻找,下一轮则从(i+1)号节点出发继续遍历寻找满足长度要求的环路。由于含有i号节点的环路在上一轮遍历中已经全部找出,因此从(i+1)号节点出发继续寻找满足长度要求的环路时,应将i号节点排除在环路节点的搜索范围之外。
d.对于经过遍历寻找初步得到的满足长度要求的环路,多条环路可能由相同的节点组成,只是连接顺序不同而已,这些环路按照赛题要求只能算作一条有效环路。因此对于遍历寻找后初步得到的满足长度要求的环路,还需要进一步去重,计算出其中的有效路径数量。
主体算法步骤如下:
(1)设置最大搜索深度MAXDEEP为8节点(通过修改msic.h文件中的MAXDEEP 宏定义实现),i=0;
(2)从节点i出发,基于图的DFS深度优先遍历(DFS也是现学的),在搜索深度不超过MAXDEEP条件约束下,不断遍历图中的节点,在遍历的过程中将节点长度为3,5,6,7,8的单向路径保存到对应长度的routem_flexarry (m取3,5,6,7,8)二维路径数组中。routem_flexarry二维路径数组的每一行存储一条长度为m的单向路径的全部节点,routem_flexarry二维路径数组的行数代表长度为m的环路的条数;

寻找满足长度要求的单向路径流程图

在搜索深度不超过MAXDEEP条件约束下,不断遍历图中未访问过的节点,在遍历的过程中将节点长度为3,5,6,7,8的单向路径保存起来
void adjlistDFSRoute(ALGraph *G, int startVertax)从start节点出发探索新路径,用于遍历单向路径
{//  printVisitedVertax(startVertax);setVisitedFlag(startVertax, 1);//标记start节点被访问 int nextVertax;push_stack(&loop_stack, startVertax);//被访问的节点存入路径序列堆栈innerStep++;//路径节点数+1if      (innerStep == 3)FlexibleArrayAppend(&route3_flexarry, loop_stack.base);else if (innerStep == 4)FlexibleArrayAppend(&route4_flexarry, loop_stack.base);else if (innerStep == 5)FlexibleArrayAppend(&route5_flexarry, loop_stack.base);else if (innerStep == 6)FlexibleArrayAppend(&route6_flexarry, loop_stack.base);else if (innerStep == 7)FlexibleArrayAppend(&route7_flexarry, loop_stack.base);else if (innerStep == 8)FlexibleArrayAppend(&route8_flexarry, loop_stack.base);if (innerStep >= MAXDEEP)//达到最大允许搜素深度 ,不允许再继续探索新节点 {//isRecall =1;return;}//没有达到允许搜索的最大深度,继续深入搜素 nextVertax = FirstNeighbor(G, startVertax);//寻找节点while (1) //keep looping {if (nextVertax != -1)//找到了一个节点{if (visitedFlag[nextVertax] == 0)// 是未访问过的新节点 {adjlistDFSRoute(G, nextVertax);//从新节点出发继续探索新节点、新路径 //if (isRecall == 1){innerStep--;pop_stack(&loop_stack, &pop_value);setVisitedFlag(nextVertax, 0);//清除访问标记//isRecall = 0;nextVertax = NextNeighbor(G, startVertax, nextVertax);//新节点可达的新路径被探索完,重新寻找新节点(路口)进行探索 continue;}}else//是已经访问过的节点 {nextVertax = NextNeighbor(G, startVertax, nextVertax);//重新寻找新节点(路口)进行探索continue;}}else  //没有找到节点 {//isRecall = 1;return;//返回上一层被调用点}}
}

(3)i++,如果i<M成立,转步骤(2),否则转步骤(4);
(4)长度为m (m取3,5,6,7,8)的routem _flexarry二维路径数组中含有大量相同起止点的单向路径。通过比较2条单向路径的起止点,得到2条单向路径的大小关系,进而对routem _flexarry二维路径数组的全部行(一维数组)使用堆排序法(堆排序时空复杂度低,排序不稳定,现学了一波常用排序算法特点),则所有长度为m的单向路径按照升序排列后重新存入routem_flexarry二维路径数组。经过本步骤,相同起止点的单向路径将被相邻排列在一起
(5)遍历长度为m的routem _flexarry二维路径数组,进行单向路径的组合拼接。其中起止点相同且中途没有重合点的2条长度为m节点单向路径可以组合拼接为1条长度为n=2m-2的环路。拼接得到的长度为n的环路保存到对应长度的cyclen_combinedbyroute_flexarry (n取4,6,8,10,12,14)二维环路数组中。cyclen_combinedbyroute_flexarry二维环路数组的每一行存储一条长度为n的环路上的全部节点(起点不重复存储),cyclen_combinedbyroute_flexarry二维环路数组的行数代表长度为n的环路的条数;
(6)将步骤(5)得到的每条环路,使用堆排序法,将节点ID升序排列后重新存入cyclen_combinedbyroute_flexarry二维环路数组。经过本步骤,相同节点组成只是连接顺序不同的环路将存储为相同的一维数组序列;
(7)长度为n的cyclen_combinedbyroute_flexarry二维环路数组中含有大量相同节点组成的重复环路。通过从高位到低位(大端模式)比较2个长度为n的一维数组,得到这2个一维数组间的大小关系,进而对cyclen_combinedbyroute_flexarry二维环路数组的全部行(一维数组)使用堆排序法,将所有长度为n的环路按照升序排列后重新存入cyclen_combinedbyroute_flexarry二维环路数组。经过本步骤,相同节点组成只是连接顺序不同的环路将被相邻排列在一起
(8)对于整体排好序的cyclen_combinedbyroute_flexarry二维环路数组,使用1个基准指针和1个游标指针遍历得到其中的非重复行数量,非重复行数量便是长度为n的有效环路的数量。对应原始问题中经手n个人的祭品最多有多少个。

2.程序源码

最近再学习下怎么用GITHUB,然后再把仓库链接贴过来。
https://github.com/callmedapeng/2020-ZTE-The-Fourier-problem-of-algorithmic-competition
鼓捣了两天又学习了一波git常规操作,妈妈再也不用担心我的版本控制问题。

3.参考博客

CSDN是个好地方,大佬们技术牛皮,还喜欢写博客交流分享——理论讲解配合代码案例,我超喜欢这里的。这次参加比赛现学了一些图这种数据的基本概念与知识,放在下面,留待以后用到时再来翻。

1.[数据结构]–图(图的遍历,最小生成树,最短路径算法)

2.数据结构:图的存储、图的遍历、最小生成树、最短路径、拓扑排序

3.图的遍历、最小生成树、最短路径

4.找出无向图中所有的环的算法

5.邻接矩阵转邻接表

6.数据结构 图的邻接表 深度优先遍历(DFS)(C语言版)

2020中兴捧月算法赛道傅里叶派赛题菜鸡回顾相关推荐

  1. Deepsort_V2 2020中兴捧月阿尔法赛道多目标检测和跟踪初赛第一名

    2020中兴捧月阿尔法赛道多目标检测和跟踪初赛第一名方案 初赛:多目标跟踪:指标MOTA和MOTP, 后期的大量实验证明检测算法相对于跟踪更重要. 数据集分析: 1.人群密集稀疏场景: 2.场景(白天 ...

  2. 2020中兴捧月算法大赛-阿尔法(MOT)赛道--赛后总结

    比赛结束了,很荣幸拿到了中兴捧月算法大赛 MOT赛道 全国总决赛第二名的亚军奖杯,这估计也是我找到工作前最后一个比赛了,收获满满,下面算是自己给自己写的一个简单的赛后总结,做的比较粗糙,细节也就不多赘 ...

  3. 2020中兴捧月算法大赛阿尔法赛道决赛总结(多目标检测与跟踪)

    赛题:多目标检测与跟踪 代码地址 初赛:排名第1 初赛思路:第一次做跟踪任务.简单的认为是检测+reid问题. 初赛: 1.首先明确题意:多目标跟踪:指标MOTA和MOTP, 后期的大量实验证明检测算 ...

  4. 2020中兴捧月算法精英挑战赛-迪杰斯特拉派初赛(未来城市物流系统)总结

    疫情关系,导致科研一直没法开展,老板着急,自己也无所事事.在清明过后看到了中兴的算法精英挑战赛,然后就开始了算法之旅,这里自己做一点总结,为自己以后争取点教训吧. 数据分析的重要性 这次比赛真的让我体 ...

  5. 2020年中兴捧月算法大赛---埃德加考特派赛题解析及代码

    写在前面 三月份疫情期间在家闲来无事, 各大公司举办了很多的算法比赛, 但是大多是人工智能相关, 而我这个菜鸡又不会这方面的, 这时发现了中兴捧月的埃德加考特派赛道, 也就是数据库相关本科课设, 恰好 ...

  6. 第一届中兴捧月算法大赛迪杰斯特拉派解决方案

    迪杰斯特拉派初赛赛题 最强大脑中的收官蜂巢迷宫变态级挑战,相信大家都叹为观止!最强大脑收官战打响后,收视率节节攀升,就连蚁后也不时出题难为一下她的子民们.在动物世界中,称得上活地图的,除了蜜蜂,蚂蚁当 ...

  7. 2019中兴捧月算法大赛历程

    1.初赛 题目是网络流量均衡.再带宽限制的图中求不同请求带宽的各条业务的最短路径使总成本最小. 解题思路: 对业务进行排序,优先级高的业务去走热点链路,优先级低的业务发现热点链路已经达到带宽上限就绕路 ...

  8. 谈谈中兴捧月大赛决赛以及总结

    前言 四月份,在师兄的推荐下,报名参加了中兴捧月大赛.一开始只是为了混一个面笔试的资格(因为提交有效成绩即可免笔试),然后为了找一个简单的赛道,注册了几个号看了两三个赛道的题目.发现自己每个都不熟悉, ...

  9. 2023第十三届“中兴捧月”全球精英挑战赛今日正式启动

    3月31日,第十三届"中兴捧月"全球精英挑战赛正式启动! 由中兴通讯主办的"中兴捧月"大赛,自2009年首次举办至今,已走过13个年头,是广大高校师生的重点关注 ...

最新文章

  1. flutter能开发游戏吗_游戏开发者都擅长“打自己的游戏”吗?
  2. YOLO学习-3:ubuntu16.04+ yolov3(darknet)+GPU(nvidia 1080ti)+opencv2.4.11 摄像头测试实践
  3. c 函数多次声明_C++核心准则C.132:不要没有理由就将函数声明为虚函数
  4. 793. 阶乘函数后K个零 golang
  5. 惊艳!28岁就任副教授,年纪轻轻已是博导、院长
  6. 苹果CMS v10模板最近很火的电影先生v1.0.2修复版
  7. cpu 保存模式的内存访问向下兼容原理
  8. 开源中国大佬是怎么用Selenium做自动化web测试的
  9. 决策树(五)--OpenCV决策树
  10. 阳新一中2021高考成绩查询,阳新一中2019高考成绩喜报、一本二本上线人数情况...
  11. 计算机网络原理 实验2《Windows Socket编程》
  12. ubuntu下opencv3和opencv2共存
  13. 全国火车高铁站及车次数据爬虫(内含100W+数据)
  14. Linux设置终端快捷键
  15. 数字电子计算机在线,(),第一台数字电子计算机问世。A、1944年B、1945年C、1946年 - 作业在线问答...
  16. 深入剖析Spring架构与设计原理(一)
  17. Euler配置yum源
  18. Flex 布局教程:语法篇
  19. 冬令营Web基础整理——Day2
  20. 闪动的TextView

热门文章

  1. 7.【kafka运维】 kafka-consumer-groups.sh消费者组管理
  2. [无人驾驶]高级驾驶辅助系统ADAS介绍
  3. iOS 高级开发 KVC(一),ios开发kvc
  4. html中链接颜色怎么不一样,css如何设置不同的超链接颜色
  5. 唐老鸭历险记Java版本,唐老鸭历险记重制版
  6. 天合光能:光伏推动中部地区崛起
  7. 抓取虎扑王者荣耀板块最近十页帖子,2.5W回帖数据 ,来看看JR们都有哪些有趣的信息
  8. 【Linux】二、Linux权限理解(总)
  9. Python练习——利用递归方法求!5(递归函数)
  10. WINDDOWS 7 下Oracle11g的TNS-12535: TNS操作超时