- 题目来源:2020华为软件精英挑战赛–初赛
- 题目说明:
2.1 输入信息:输入为包含资金流水的文本文件,每一行代表一次资金交易记录,包含本端账号ID, 对端账号ID, 转账金额,用逗号隔开。
本端账号ID和对端账号ID为一个32位的无符号整数
转账金额为一个32位的无符号整数
转账记录最多为28万条
每个账号平均转账记录数< 10
账号A给账号B最多转账一次
举例如下,其中第一行[1,2,100]表示ID为1的账户给ID为2的账户转账100元:
1,2,100
1,3,100
2,4,90
3,4,50
4,1,95
2,5,95
5,4,90
4,6,30
6,7,29
7,4,28
2.2 输出信息:输出信息为一个文件,包含如下信息:
第一行输出:满足限制条件下的循环转账个数。
说明:数据集经过处理,会保证满足条件的循环转账个数小于300万。
第二行开始:输出所有满足限制条件的循环转账路径详情。
输出循环转账路径要按照指定排序策略进行排序:每条循环转账中,ID(ID转为无符号整数后)最小的第一个输出;总体按照循环转账路径长度升序排序;同一级别的路径长度下循环转账账号ID序列,按照字典序(ID转为无符号整数后)升序排序。
举例如下:
4
1,2,4
1,3,4
4,6,7
1,2,5,4
2.3 限制条件:循环转账的路径长度最小为3(包含3)最大为7(包含7),例如账户A给账户B转账,账户B给账户A转账,循环转账的路径长度为2,不满足循环转账条件。
- 题目理解:

说明:2,4,1,2 是长度为 3 的环,按照升序的要求是:1,2,4
本案例是以邻接表的形式找环,利用 sort 对 graph.keys() 得到的 key 值进行从小到大的排序,为了在找环过程中出现重复找环的情况,进行了剪枝优化,即:比自己小的 key 不再去查找,本案例用的最基本的 for 循环,对于十万以内的环查找速度较快,但是不建议用python 程序参加比赛,主要是太慢了。当然自己也想过用多进程多线程进行优化,然而效果并没有多大的提升,本文可以很好的帮助小白理解操作,大佬不喜勿喷啊,毕竟作为一个妹子码代码不容易,自己一个人走了太多的弯路了,不过个人很欢迎大佬前来指导一二。
废话不多说,下面上代码。
import time
def func(graph,s):
path =[]
for x1 in graph[s]:
if x1 > s:
try:
nodes2 = graph[x1]
except KeyError as e:
pass
else:
for x2 in nodes2:
if x2 > s:
try:
nodes3 = graph[x2]
except KeyError as e:
pass
else:
for x3 in nodes3:
if s == x3:
A = [s,x1,x2]
if len(set(A)) == len(A):