鱼C论坛

 找回密码
 立即注册
楼主: jerryxjr1220

[已解决]鱼C论坛python挑战赛(01期)

[复制链接]
 楼主| 发表于 2017-6-17 07:50:21 From FishC Mobile | 显示全部楼层
Teagle 发表于 2017-6-17 07:46
怎么可能没有呢

L = ['AhCBDk','ADBekC','eCBDgD','CABghD']

['A', 'h', 'e', 'C', 'A', 'g', 'h', 'B', 'D', 'B', 'e', 'k', 'g', 'D']

我说的是这条,对照你提交的答案和原始列表
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 10:11:38 | 显示全部楼层
SixPy 发表于 2017-6-16 21:01
L = ['AhCBDk','ADBekC','eCBDgD','CABghD']

用你的程序试试这个~
  1. ##L = ['ACBD','ADBC','CBDD','CABD']
  2. L = ['AhCBDk','ADBekC','eCBDgD','CABghD']
  3. result = []
  4. mmin = 100

  5. def check(l):
  6.     for each in l:
  7.         if each != '':
  8.             return False
  9.     return True

  10. def poplist(l):
  11.     x = []
  12.     for each in l:
  13.         if each != '':
  14.             x.append(each[0])
  15.     x = list(set(x))
  16.     x.sort()
  17.     return x

  18. def dele(l, x):
  19.     y = [ ]
  20.     for each in l:
  21.         if each == '':
  22.             y.append(each)
  23.         else:
  24.             if each[0] == x:
  25.                 y.append(each[1:])
  26.             else:
  27.                 y.append(each)
  28.     return y


  29. def dfs(step, l):
  30.     global mmin
  31.     if check(l):
  32. ##        result.append(step)
  33.         if mmin > step:
  34.             mmin = step
  35.         return
  36.     x = poplist(l)
  37.     for each in x:
  38.         lx = dele(l, each)
  39.         dfs(step+1, lx)
  40.         
  41. dfs(0, L)
  42. ##print(min(result))
  43. print(mmin)
复制代码

计算出来是13,之前用result记录所有的情况列表太大了,所以稍微调整了下程序,用一个mmin记录最小值,不过计算的时间挺长的~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 12:38:37 | 显示全部楼层
修改好了,这次绝对可以!!

整的我在考试的时候就在担心,会不会有人抢在我前头提交

  1. # 基列表挑选准则:挑选含不同字母多的字符串
  2. def base(a):
  3.     c = []
  4.     for i in range(len(a)):
  5.         c.append(len(set(a[i])))
  6.     return (c.index(max(c))) #返回符合要求的字符串在列表中的位置

  7. # 次列表的挑选准则:挑选字母在基列表中位置靠前的字符串,如果没有则选择第一个字符串
  8. def less(a,a_base):
  9.     if len(a) == 1:
  10.         return 0
  11.     else:
  12.         temp = []
  13.         for i in a_base:
  14.             for j in range(len(a)):
  15.                 try:
  16.                     temp.append(a[j].index(i))
  17.                 except ValueError:
  18.                     temp.append(len(a[j]))
  19.             if min(temp)<len(a[j]):
  20.                 return(temp.index(min(temp))) #返回符合要求的字符串在列表中的位置
  21.         return 0 #如果没有与基列表重复的字母,则选择第一个字符串

  22. # 寻找所有的匹配组合,返回匹配超度最长的组合。
  23. def seek_index(a_base,a_less):
  24.     #返回在主列表中的位置T=[组合1,..,组合n] 组合1=[位置0,...,位置n]
  25.     T = []
  26.     for i in range(len(a_less)):
  27.         temp = []        
  28.         for j in range(i,len(a_less)):
  29.             if temp==[]:
  30.                 k=0
  31.             try:
  32.                 k = a_base.index(a_less[j],k)
  33.                 temp.append(k) #偶数位置是对应元素在基列表中的位置
  34.                 temp.append(j) #奇数位置是对应元素在次列表中的位置
  35.                 k += 1
  36.             except ValueError:
  37.                 pass
  38.             
  39.         T.append(temp)
  40.     #返回最长组合
  41.     temp = []
  42.     for k in T:        
  43.         temp.append(len(k))
  44.     return (T[temp.index(max(temp))])

  45. #利用得到的最优匹配位置进行匹配,在基列表中插入不满足次列表的元素
  46. def match(a_base,a_less,index):

  47.     temp_base = []
  48.     temp_less = []
  49.     for i in range(len(index)):
  50.         if not i % 2:
  51.             temp_base.append(index[i])#得到对应元素在基列表中的位置
  52.         else:
  53.             temp_less.append(index[i])#得到对应元素在次列表中的位置

  54.     for i in range(len(temp_less)):

  55.         if i == 0:
  56.             if temp_less[i] != 0:
  57.                 temp = a_less[:temp_less[i]]
  58.                 temp.reverse()
  59.                 for j in range(len(temp)):
  60.                     a_base.insert(temp_base[i],temp[j])
  61.                 for k in range(i+1,len(temp_base)):
  62.                     temp_base[k] += len(temp)
  63.             
  64.         else:
  65.             if temp_less[i] - temp_less[i-1] > 1:
  66.                
  67.                 temp = a_less[temp_less[i-1]+1:temp_less[i]]
  68.                 temp.reverse()               
  69.                 for j in range(len(temp)):
  70.                     a_base.insert(temp_base[i],temp[j])
  71.                 if i != len(temp_less)-1:
  72.                     for k in range(i+1,len(temp_base)):
  73.                         temp_base[k] += len(temp)
  74.                     
  75.             if i == len(temp_less)-1 and temp_less[i] < len(a_less)-1:
  76.                 temp = a_less[temp_less[i]+1:]
  77.                 for j in range(len(temp)):
  78.                     a_base.append(temp[j])

  79.     return a_base            
  80.         
  81.    
  82. L = ['ACBD','ADBC','CBDD','CABD']
  83. ##L = ['AhCBDk','ADBekC','eCBDgD','CABghD']


  84. list_base = list(L[base(L)]) # 挑选基列表
  85. L.remove(''.join(list_base)) # 在L中移除选中的基列表所对应的字符串

  86. for i in range(len(L)):
  87.     list_less = list(L[less(L,list_base)]) #挑选次列表
  88.     L.remove(''.join(list_less))# 在L中移除选中的次列表中对应的字符串
  89.     nice_index = seek_index(list_base,list_less) #查找最佳匹配顺序
  90.     list_base = match(list_base,list_less,nice_index) #进行匹配

  91.    
  92. print (list_base)
  93. print (len(list_base))

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 12:39:54 | 显示全部楼层
SixPy 发表于 2017-6-16 21:01
L = ['AhCBDk','ADBekC','eCBDgD','CABghD']

用你的程序试试这个~
  1. ['A', 'h', 'e', 'C', 'A', 'B', 'g', 'h', 'D', 'B', 'e', 'k', 'C', 'g', 'D']
  2. 15
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 14:19:45 | 显示全部楼层
本帖最后由 wei_Y 于 2017-6-17 20:29 编辑

贡献个低效率版本。

递归,俗称暴力破解。
  1. def combinations(rawList):
  2.     result = ['']
  3.    
  4.     length = 0

  5.     currentStr = ''

  6.     def combination(rawList, currentStr, currentLength=0):
  7.         # 列表不需要进行nonlocal操作也可以直接操作。
  8.         nonlocal length

  9.         # 在计算时减少不必要的长度。
  10.         if length:
  11.             # 大于当前最小长度,直接返回。
  12.             if currentLength > length:
  13.                 return
  14.             # 等于当前最小长度,但是还可以计算,直接返回。
  15.             if currentLength == length and any(rawList):
  16.                 return

  17.         # 祈祷一下?
  18.         # 它的顺序直接决定效率。低或高大约相差3~5倍。
  19.         currentWords = {i[0] for i in rawList if i}
  20.         
  21.         if not currentWords:
  22.             # 正常迭代的结果。
  23.             result[0] = currentStr
  24.             length = currentLength
  25.             return

  26.         # 每次都将各个字符串的第一个字符作为种子,
  27.         # 将相同的字符清空,继续递归。(因为也会清空来源所以不会无限递归。)
  28.         # 例: 'CBDD', 'CABD', 'ACBD', 'ADBC'
  29.         # C清空后。BDD ABD ACBD ADBC.
  30.         # [BDD ABD ACBD ADBC], C, 1
  31.         # 接下来会清空 B 与 A。结果分别会生成 CB开始 与 A开始的两个分支。

  32.         for j in currentWords:
  33.             # 字符串不需要深拷贝。
  34.             copyList = rawList.copy()
  35.             
  36.             for index, data in enumerate(copyList):
  37.                 if data:
  38.                     if data[0] == j:
  39.                         copyList[index] = data[1:]

  40.             combination(copyList, currentStr+j, currentLength+1)

  41.     combination(rawList, currentStr)

  42.     return result
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-17 16:15:44 From FishC Mobile | 显示全部楼层
挑战赛第二天,目前提交答案的有三位鱼油,最终评选结果将在挑战截止日期后公布,欢迎继续提交优秀的解答程序!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 17:35:36 | 显示全部楼层
最终版,这次绝对是可以的,绝对是正确的!!


  1. from itertools import combinations
  2. # 基列表挑选准则:挑选含不同字母多的字符串
  3. def base(a):
  4.     c = []
  5.     for i in range(len(a)):
  6.         c.append(len(set(a[i])))
  7.     return (c.index(max(c))) #返回符合要求的字符串在列表中的位置

  8. # 次列表的挑选准则:挑选字母在基列表中位置靠前的字符串,如果没有则选择第一个字符串
  9. def less(a,a_base):
  10.     if len(a) == 1:
  11.         return 0
  12.     else:
  13.         temp = []
  14.         for i in a_base:
  15.             for j in range(len(a)):
  16.                 try:
  17.                     temp.append(a[j].index(i))
  18.                 except ValueError:
  19.                     temp.append(len(a[j]))
  20.             if min(temp)<len(a[j]):
  21.                 return(temp.index(min(temp))) #返回符合要求的字符串在列表中的位置
  22.         return 0 #如果没有与基列表重复的字母,则选择第一个字符串

  23. # 寻找所有的匹配组合,返回匹配长度最长的组合。
  24. def seek_index(a_base,a_less):
  25.    
  26.     T = []
  27.     all_index = []
  28.     #列出所有的次列表进行匹配的元素的所有可能性,将对应位置放到all_index列表
  29.     for i in range(len(a_less)):
  30.         all_index.extend(combinations(range(len(a_less)),i+1))
  31.         
  32.     for i in range(len(all_index)):
  33.         temp = []
  34.         for j in range(len(all_index[i])):
  35.             index = all_index[i][j] #a_less中的位置
  36.             if temp == []:
  37.                 k = 0
  38.             try :
  39.                 k = a_base.index(a_less[index],k)
  40.                 temp.append(k)
  41.                 temp.append(index)
  42.                 k += 1
  43.             except ValueError:
  44.                 pass
  45.         T.append(temp)  
  46.      
  47.     #返回最长组合
  48.     temp = []
  49.     for k in T:        
  50.         temp.append(len(k))
  51.     return (T[temp.index(max(temp))])

  52. #利用得到的最优匹配位置进行匹配,在基列表中插入不满足次列表的元素
  53. def match(a_base,a_less,index):

  54.     temp_base = []
  55.     temp_less = []
  56.     for i in range(len(index)):
  57.         if not i % 2:
  58.             temp_base.append(index[i])#得到对应元素在基列表中的位置
  59.         else:
  60.             temp_less.append(index[i])#得到对应元素在次列表中的位置

  61.     for i in range(len(temp_less)):

  62.         if i == 0:
  63.             if temp_less[i] != 0:
  64.                 temp = a_less[:temp_less[i]]
  65.                 temp.reverse()
  66.                 for j in range(len(temp)):
  67.                     a_base.insert(temp_base[i],temp[j])
  68.                 for k in range(i+1,len(temp_base)):
  69.                     temp_base[k] += len(temp)
  70.             
  71.         else:
  72.             if temp_less[i] - temp_less[i-1] > 1:
  73.                
  74.                 temp = a_less[temp_less[i-1]+1:temp_less[i]]
  75.                 temp.reverse()               
  76.                 for j in range(len(temp)):
  77.                     a_base.insert(temp_base[i],temp[j])
  78.                 if i != len(temp_less)-1:
  79.                     for k in range(i+1,len(temp_base)):
  80.                         temp_base[k] += len(temp)
  81.                     
  82.             if i == len(temp_less)-1 and temp_less[i] < len(a_less)-1:
  83.                 temp = a_less[temp_less[i]+1:]
  84.                 for j in range(len(temp)):
  85.                     a_base.append(temp[j])

  86.     return a_base            
  87.         
  88.    
  89. L = ['ACBD','ADBC','CBDD','CABD']
  90. L = ['AhCBDk','ADBekC','eCBDgD','CABghD']


  91. list_base = list(L[base(L)]) # 挑选基列表
  92. L.remove(''.join(list_base)) # 在L中移除选中的基列表所对应的字符串

  93. for i in range(len(L)):
  94.     list_less = list(L[less(L,list_base)]) #挑选次列表
  95.     L.remove(''.join(list_less))# 在L中移除选中的次列表中对应的字符串
  96.     nice_index = seek_index(list_base,list_less) #查找最佳匹配顺序
  97.     list_base = match(list_base,list_less,nice_index) #进行匹配
  98.    
  99. print (list_base)
  100. print (len(list_base))

复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +2 收起 理由
jerryxjr1220 + 5 + 5 + 2 答题奖励

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 19:55:02 | 显示全部楼层
我的思路有点特别,计算机就是为计算而生
根据题目,答案并不唯一,所以我用的是抽样穷举法

思路是用已有的元素随机组合,然后匹配生成较短的母字符
代码还有待改进,使用排列组合生成母字符应该更好

  1. import re
  2. from random import randrange


  3. c=[]

  4. a_base='AhCBDk ADBekC eCBDgD CABghD'.split()

  5. len_base=len(''.join(a_base))
  6. for l in range(20000):#重复运行次数
  7.     base=''#用于记录生成的母字符
  8.     a=a_base[:]#复制列表,用于查找母字符
  9.     #随机生成母字符,思路:每次从a列表中抽取任意一个元素的最左边的字符
  10.     for i in range(len_base):#
  11.         r=randrange(len(a))
  12.         while True:#若抽中的元素为空,取下一个元素
  13.             if a[r]!="":
  14.                 break
  15.             r=(r+1)%4
  16.         base+=a[r][0]#接上,生成母字符base
  17.         
  18.         a[r]=a[r][1:]#去除左边第一个字符
  19.     #print(base)

  20.     b=[0]*len(base)#用于记录查到找的字符
  21.    
  22.     a=a_base[:]#复制列表,用于查找母字符

  23.     for i in a: #遍历每一个元素,查找字符对应的位置并记录
  24.         s_count=0 #
  25.         for j in range(len(base)):#j遍历base的每一个字符,与i的字符比较,s_count记录i中的顺序
  26.             
  27.             if i[s_count]==base[j]:#如果一样,s_count+1,即判断i的下一个字符
  28.                 b[j]=1  #b对应的位置设置为1
  29.                 s_count+=1
  30.             if s_count==len(i):#如果查找完毕,退出,判断下一个元素
  31.                 break
  32.     temp=''.join([base[i] for i in range(len(base)) if b[i]==1])
  33.     if len(temp)<=13:
  34.         c.append(temp)
  35.    

  36. c=set(c)#去除重复项
  37. a=a_base[:]
  38. #print(c)
  39. #以下展示用
  40. for w in c:
  41.     if len(w)<=13:
  42.         
  43.         for i in a:
  44.             s_count=0
  45.             for j in range(len(w)):
  46.                 if i[s_count]==w[j]:
  47.                     print(w[j],end="")
  48.                     s_count+=1
  49.                 else:
  50.                     print(' ',end='')
  51.                 if s_count==len(i):
  52.                     break
  53.             print('')
  54.         print(w)
复制代码


我找到了长度为13的哦
  A   hCBD k
  A D   B ekC
eC BDg   D
CAB gh  D
eCABDghCBDekC  #这个
  A   hCB Dk
  A D   Be kC
eC BDg    D
CAB gh   D
eCABDghCBeDkC#这个

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +2 收起 理由
jerryxjr1220 + 5 + 5 + 2 答题奖励

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-17 23:13:07 | 显示全部楼层
达锅 发表于 2017-6-17 19:55
我的思路有点特别,计算机就是为计算而生
根据题目,答案并不唯一,所以我用的是抽样穷举法

很明显你做的结果错了哦
你的结果应该是
ecacbdghcbedkc
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-18 02:18:00 | 显示全部楼层
本帖最后由 达锅 于 2017-6-18 02:19 编辑
瓦蓝 发表于 2017-6-17 23:13
很明显你做的结果错了哦
你的结果应该是
ecacbdghcbedkc


没错,因为随机数不够大,你试一下40000,或者多运行几次就看到了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-18 13:35:53 | 显示全部楼层
Teagle 发表于 2017-6-17 17:35
最终版,这次绝对是可以的,绝对是正确的!!

如果L=['1','2','3','4']
你的程序的结果是什么?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-18 14:03:00 | 显示全部楼层
精英挑战赛最后一天,目前已经有4位鱼油提交了答案。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-18 20:40:41 | 显示全部楼层
jerryxjr1220 发表于 2017-6-18 13:35
如果L=['1','2','3','4']
你的程序的结果是什么?

唉,我已经意识到我的程序是错误的了,不完善。。
唉,编程的经验太少,我还得继续多做练习,
谢谢大佬的鼓励

评分

参与人数 1鱼币 +5 收起 理由
SixPy + 5 继续努力~

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-18 23:47:45 | 显示全部楼层
Teagle 发表于 2017-6-18 20:40
唉,我已经意识到我的程序是错误的了,不完善。。
唉,编程的经验太少,我还得继续多做练习,
谢谢大佬 ...

,感谢大佬,我今天真是太幸运了,被两位大神鼓励
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-19 00:09:04 | 显示全部楼层
本帖最后由 lh625243422 于 2017-6-19 00:37 编辑
  1. import random
  2. r=random.randint
  3. l=['ACBD','ADBC','CBDD','CABD']
  4. first=list(l[0])
  5. rest=''.join(list(l[1:]))
  6. def is_sub(s, strings):
  7.     if len(s) == 1 and s in strings:
  8.         return True
  9.     if s[0] not in strings:
  10.         return False
  11.     return is_sub(s[1:], strings[strings.find(s[0])+1:])
  12. def sr(s):
  13.     b1=s
  14.     for i in s:
  15.         b1=b1.replace(i+i,i,1)   
  16.     return b1

  17. def lh(x,y):#将剩余部分随机插入第一个字符串中
  18.     z=x[:]
  19.     n=0
  20.     for i in range(len(y)):
  21.         if i%len(first)==0:       #在同一个字符串中必然后插入的在先插入的后面
  22.             n=r(0,len(z))
  23.         else:
  24.             n=r(n+1,len(z)) #在同一个字符串中必然后插入的在先插入的后面
  25.         z.insert(n,y[i])
  26.     c=''.join(z)
  27.     return sr(c)
  28. d={}
  29. for i in range(200000):
  30.     st=lh(first,rest)
  31.     if is_sub(l[0],st) and is_sub(l[1],st) and is_sub(l[2],st) and is_sub(l[3],st):#此处可不判断,会产生最短7位的,但CBDD没匹配上,加上一个D就是8位
  32.         lst=len(st)
  33.         d[lst]=st
  34.    
  35. print(min(d.keys()),':',d[min(d.keys())])
复制代码

采用思想是随机插入法消除相邻相同的字符,要求每个字符串的长度一致,随机次数越多越好,不会产生CACBDDBC这样的母字符串

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +2 收起 理由
jerryxjr1220 + 5 + 5 + 2 答题奖励

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-19 11:00:42 | 显示全部楼层
SixPy 发表于 2017-6-16 15:07
早就写好了,不想发,怕影响其他人的思路。
等等看~

期待看看你的解答。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-19 14:37:35 | 显示全部楼层
答案已经出来了,我贡献一个我找到的解题思路的ppt给各位参考参考。这东西其实我第一天就找到了,不过最近事情有点多,加上这种题目也不是我擅长的,所以解不了题。版权当然还是归PPT里面那位作者的了。没有代码,只有思路,不过基本应该和wei_y的差不多,BFS的思路。

6_xlcd_160320039.rar

30.32 KB, 下载次数: 10

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-19 15:05:51 | 显示全部楼层
ooxx7788 发表于 2017-6-19 14:37
答案已经出来了,我贡献一个我找到的解题思路的ppt给各位参考参考。这东西其实我第一天就找到了,不过最近 ...

不错,解题思路基本都是一致的。
我写的递归插入法也是同样原理。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-19 20:59:19 | 显示全部楼层
还有这种比赛
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-6-21 10:54:00 | 显示全部楼层

@~风介~ 帮发个系统消息宣传一下呗~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-9-27 02:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表