当前位置:   article > 正文

蓝桥杯国赛备赛刷题总结(一)_蓝桥杯 刷题

蓝桥杯 刷题

一.Sine之舞

最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功。所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力。
不妨设
An=sin(1–sin(2+sin(3–sin(4+...sin(n))...)
Sn=(...(A1+n)A2+n-1)A3+...+2)An+1
FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题。

思路:简单的递归函数,要注意断点处的值

  1. def ann(n,s):
  2. if n%2==1:
  3. ans='sin('+str(n)+'-'+s+')'
  4. else:
  5. ans = 'sin(' + str(n) + '+' + s + ')'
  6. if n==1:
  7. return ans
  8. else:
  9. return ann(n-1,ans)
  10. def an(n,s):
  11. s='sin('+str(n)+')'
  12. if n==1:
  13. return s
  14. return ann(n-1,s)
  15. def sn(n,s):
  16. global N
  17. if n==N:
  18. return s+an(n,'')+'+'+str(1)
  19. else:
  20. s='('+s+an(n,'')+'+'+str(N-n+1)+')'
  21. return sn(n+1,s)
  22. N=eval(input())
  23. print(sn(1,''))

二.矩形面积交

平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。

思路:先分别计算出长和宽相交的长度,再相乘计算出面积,注意要考虑重合时的多种情况

  1. a=list(map(eval,input().strip().split()))
  2. b=list(map(eval,input().strip().split()))
  3. def cha(c,d,e,f):
  4. #判断相交关系
  5. if e>=c and e<=d:
  6. return min(d,f)-e
  7. if f>=c and f<=d:
  8. return f-max(c,e)
  9. #判断包含关系
  10. if e<=c and f>=d:
  11. return d-c
  12. if c<=e and d>=f:
  13. return f-e
  14. return 0
  15. print("{:.2f}".format(cha(min(a[0],a[2]),max(a[0],a[2]),min(b[0],b[2]),max(b[0],b[2]))*cha(min(a[1],a[3]),max(a[1],a[3]),min(b[1],b[3]),max(b[1],b[3]))))

三.报时助手

给定当前的时间,请用英文的读法将它读出来。
时间用时h和分m表示,在英文的读法中,读一个时间的方法是:
如果m为0,则将时读出来,然后加上“o'clock”,如3:00读作“three  o'clock”。
如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five  thirty”。
时和分的读法使用的是英文数字的读法,其中0~20读作:
0:zero,  1:  one,  2:two,  3:three,  4:four,  5:five,  6:six,  7:seven,  8:eight,  9:nine,  10:ten,  11:eleven,  12:twelve,  13:thirteen,  14:fourteen,  15:fifteen,  16:sixteen,  17:seventeen,  18:eighteen,  19:nineteen,  20:twenty。
30读作thirty,40读作forty,50读作fifty。
对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty  one”。
按上面的规则21:54读作“twenty  one  fifty  four”,9:07读作“nine  seven”,0:15读作“zero  fifteen”。

注意:数字前面有0用int()而不是eval()

  1. num={0:'zero', 1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine', 10:'ten', 11:'eleven', 12:'twelve', 13:'thirteen', 14:'fourteen', 15:'fifteen', 16:'sixteen', 17:'seventeen', 18:'eighteen', 19:'nineteen', 20:'twenty'}
  2. a,b=map(int,input().strip().split())
  3. if a<=20:
  4. print(num[a],end=' ')
  5. else:
  6. print(num[20],num[a%20],end=' ')
  7. if b==0:
  8. print("o'clock")
  9. elif b<=20:
  10. print(num[b])
  11. else:
  12. n=[0,0,'twenty','thirty','forty','fifty']
  13. if b%10==0:
  14. print(n[b//10])
  15. else:
  16. print(n[b // 10], num[b % 10])

四.数的读法

Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。
比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。
所以,他迫切地需要一个系统,然后当他输入12  3456  7009时,会给出相应的念法:
十二亿三千四百五十六万七千零九
用汉语拼音表示为
shi  er  yi  san  qian  si  bai  wu  shi  liu  wan  qi  qian  ling  jiu
这样他只需要照着念就可以了。
你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。
注意必须严格按照规范,比如说“10010”读作“yi  wan  ling  yi  shi”而不是“yi  wan  ling  shi”,“100000”读作“shi  wan”而不是“yi  shi  wan”,“2000”读作“er  qian”而不是“liang  qian”。

思路:先将数字划分为每四位一组:"亿","万",然后每组进行读数,之后再考虑特殊的读"yi"的情况,注意考虑每组之间读'ling'的问题.

  1. def readnum(n):
  2. ans=''
  3. global num_list
  4. if n//1000>0:
  5. ans+=str(num_list[n//1000])+' qian '
  6. n%=1000
  7. if n//100>0:
  8. ans+=str(num_list[n//100])+' bai '
  9. n %= 100
  10. if n // 10 > 0:
  11. ans +=str(num_list[n // 10]) + ' shi '
  12. if n % 10 > 0:
  13. ans +=str(num_list[n % 10])
  14. else:
  15. if n % 10 > 0:
  16. ans += 'ling ' + str(num_list[n % 10])
  17. else:
  18. n%=100
  19. if n//10>0:
  20. ans+='ling '+str(num_list[n//10])+' shi '
  21. if n%10>0:
  22. ans+=str(num_list[n%10])
  23. else:
  24. if n%10>0:
  25. ans+='ling '+str(num_list[n%10])
  26. else:
  27. if n//100>0:
  28. ans+=str(num_list[n//100])+' bai '
  29. n %= 100
  30. if n // 10 > 0:
  31. ans +=str(num_list[n // 10]) + ' shi '
  32. if n % 10 > 0:
  33. ans +=str(num_list[n % 10])
  34. else:
  35. if n % 10 > 0:
  36. ans += ' ling ' + str(num_list[n % 10])
  37. else:
  38. n%=100
  39. if n//10>0:
  40. if n//10==1:
  41. ans+='shi '
  42. else:
  43. ans+=str(num_list[n//10])+' shi '
  44. if n % 10 > 0:
  45. ans += str(num_list[n % 10])
  46. else:
  47. if n%10>0:
  48. ans+=str(num_list[n%10])
  49. return ans.strip()
  50. num=eval(input().strip())
  51. num_list=['ling','yi','er','san','si','wu','liu','qi','ba','jiu','shi']
  52. ans=''
  53. if num//100000000>0:
  54. a=num//100000000
  55. ans+=readnum(a)+' yi '
  56. num%=100000000
  57. if num//10000>0:
  58. if len(ans)>1 and ans[-2]=='i' and num//10000000==0:
  59. ans+='ling '
  60. a=num//10000
  61. ans+=readnum(a)+' wan '
  62. num%=10000
  63. if num>0:
  64. if len(ans)>1 and ans[-2] in ['i','n'] and num//1000==0:
  65. ans+='ling '
  66. ans+=readnum(num)
  67. print(ans.strip())

五.数组替换

编写并测试如下函数:
void  Add  (int  a[],  int  m,  int  b[],  int  n);
该函数将数组b的前n个元素追加到数组a的前m个元素后,假定数组a具有至少存放m+n个元素的空间。例如,如果数组a为  {22,33,44,55,66,77,88,99},数组b为{20,30,40,50,60,70,80,90},则调用Add(a,5,b,3)  后,将把数组a变为{22,33,44,55,66,20,30,40}。注意数组b并没有改变,而且数组a中只需改变n个元素。

注意:如果a数组还有剩余的空间的话,a数组剩余的元素也要输出

  1. nm=input()
  2. a=list(map(eval,input().strip().split()))
  3. b=list(map(eval,input().strip().split()))
  4. m,n=map(eval,input().split())
  5. ans=[]
  6. for i in range(m):
  7. ans.append(a[i])
  8. for i in range(n):
  9. ans.append(b[i])
  10. if len(ans)<len(a):
  11. for i in range(len(ans),len(a)):
  12. ans.append(a[i])
  13. for i in range(len(ans)-1):
  14. print(ans[i],end=',')
  15. print(ans[len(ans)-1])

六.分苹果

小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号1..N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。
最后老师想知道每个小朋友有多少苹果。

思路:在一个区间上将数做加减法时利用差分数组,直接简化为在端点进行加减法.

  1. from collections import defaultdict
  2. N,M=map(eval,input().split())
  3. d=defaultdict(int)
  4. for i in range(M):
  5. l,r,c=map(int,input().split())
  6. d[l]+=c
  7. d[r+1]-=c
  8. ans=0
  9. for i in range(1,N+1):
  10. ans+=d[i]
  11. print(ans,end=' ')

七.产生数

给出一个整数  n 和  k  个变换规则。规则:一位数可变换成另一个一位数:规则的右部不能为零。
例如:n=234。有规则(k=2):
2->   5
3->   6
上面的整数  234  经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共  4  种不同的产生数
问题:给出一个整数  n  和  k  个规则。求出:经过任意次的变换(0次或多次),能产生出多少个不同整数。仅要求输出个数。

思路:构建一个10*10的有向图,代表每种数字可以转换的数字,之后用Floyd算法求出连通块,再根据输入的数字算出答案

  1. n,k=map(int,input().split())
  2. m=[[float('inf') for i in range(10)]for j in range(10)]
  3. for i in range(10):
  4. m[i][i]=1
  5. for i in range(k):
  6. a,b=map(int,input().split())
  7. m[a][b]=1
  8. for k in range(10):
  9. for i in range(10):
  10. for j in range(10):
  11. m[i][j]=min(m[i][j],m[i][k]+m[k][j])
  12. c=[0 for i in range(10)]
  13. for i in range(10):
  14. for j in range(10):
  15. if m[i][j]<float('inf'):
  16. c[i]+=1
  17. ans=1
  18. while n:
  19. ans*=c[n%10]
  20. n//=10
  21. print(ans)

八.传染病控制

研究表明,这种传染病的传播具有两种很特殊的性质;
第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不得病,或者是XY之间的传播途径被切断,则X就不会得病。
第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一代患者,而不会再传播给下一代。
这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中  心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也  就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个  切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。

思路:先用链表保存输入的连接关系,之后再将他们构造成一棵树,这样可以减少复杂度,再使用dfs寻找最少的感染人数

  1. n,p=map(int,input().split())
  2. linklist=[[] for i in range(n+1)]
  3. for i in range(p):
  4. a,b=map(int,input().split())
  5. linklist[a].append(b)
  6. linklist[b].append(a)
  7. tree=[[] for i in range(n+1)]
  8. def createTree(num):
  9. global tree,linklist
  10. if len(linklist[num])==0:
  11. return
  12. else:
  13. tree[num]=linklist[num][:]
  14. for i in linklist[num]:
  15. linklist[i].remove(num)
  16. createTree(i)
  17. return
  18. createTree(1)
  19. ans=300
  20. def dfs(curFloor,curans):
  21. global ans,tree
  22. nextFloor=[]
  23. minans=300
  24. for i in curFloor:
  25. nextFloor+=tree[i]
  26. if nextFloor==[]:
  27. if curans<ans:
  28. ans=curans
  29. return 0
  30. elif len(nextFloor)-1+curans<=ans:
  31. for i,x in enumerate(nextFloor):
  32. del nextFloor[i]
  33. nextans=dfs(nextFloor,curans+len(nextFloor)-1)
  34. if minans>nextans:
  35. minans=nextans
  36. nextFloor.insert(i,x)
  37. return len(nextFloor)-1+minans
  38. else:
  39. return 300
  40. print(dfs([1],1)+1)

九.士兵排队问题

有N个士兵(1≤N≤26),编号依次为  A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较  结果(P1、P2∈A,B,C,…,Z,记为  P1> P2),如”A> B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)

思路:拓扑排序问题

  1. num=set()
  2. linklist=[[] for i in range(26)]
  3. while True:
  4. try:
  5. a,b=input().split('>')
  6. num.add(ord(a)-ord('A'))
  7. num.add(ord(b)-ord('A'))
  8. linklist[ord(a)-ord('A')].append(ord(b)-ord('A'))
  9. except:
  10. break
  11. GT=[[0 for i in range(26)]for j in range(26)]
  12. for i in range(26):
  13. for j in linklist[i]:
  14. GT[j][i]=1
  15. ans=''
  16. while len(num):
  17. flag=True
  18. for i in range(26):
  19. if i in num and sum(GT[i])==0:
  20. ans+=chr(i+ord('A'))
  21. num.remove(i)
  22. for j in linklist[i]:
  23. GT[j][i]=0
  24. flag=False
  25. if flag:
  26. ans='No Answer!'
  27. break
  28. print(ans)

十.素数求和

输入一个自然数n,求小于等于n的素数之和

思路:素数筛模板

  1. n=int(input())
  2. ai=[0 for i in range(n+1)]
  3. for i in range(2,int(n**0.5)+2):
  4. if ai[i]==0:
  5. for j in range(i*i,n+1,i):
  6. ai[j]=1
  7. ans=0
  8. for i in range(2,n+1):
  9. if ai[i]==0:
  10. ans+=i
  11. print(ans)

十一.进制转换

程序提示用户输入三个字符,每个字符取值范围是0-9,A-F。然后程序会把这三个字符转化为相应的十六进制整数,并分别以十六进制,十进制,八进制输出。

  1. s=input().lstrip('0')
  2. s=s.strip()
  3. ans=[]
  4. if len(s)==0:
  5. s='0'
  6. ans.append(s)
  7. d=dict()
  8. d['A']=10
  9. d['B']=11
  10. d['C']=12
  11. d['D']=13
  12. d['E']=14
  13. d['F']=15
  14. f10=0
  15. for i in s:
  16. try:
  17. f10=f10*16+int(i)
  18. except:
  19. f10=f10*16+d[i]
  20. ans.append(str(f10))
  21. f8=''
  22. while f10:
  23. f8+=str(f10%8)
  24. f10//=8
  25. if len(f8)==0:
  26. f8='0'
  27. ans.append(f8[::-1])
  28. s=' '.join(ans)
  29. print(s)

十二.欧拉函数

给定一个大于1,不超过2000000的正整数n,输出欧拉函数,phi(n)的值。
如果你并不了解欧拉函数,那么请参阅提示。
欧拉函数phi(n)是数论中非常重要的一个函数,其表示1到n-1之间,与n互质的数的个数。显然的,我们可以通过定义直接计算phi(n)。
当然,phi(n)还有这么一种计算方法。
首先我们对n进行质因数分解,不妨设n=p1^a1  *  p2^a2  *  ...  *  pk^ak  (这里a^b表示a的b次幂,p1到pk为k个互不相同的质数,a1到ak均为正整数),那么
phi(n)=n(1-(1/p1))(1-(1/p2))....(1-(1/pk))
稍稍化简一下就是
phi(n)=n(p1-1)(p2-1)...(pk-1)/(p1*p2*...*pk)
计算的时候小心中间计算结果超过int类型上界,可通过调整公式各项的计算顺序避免(比如先做除法)!

  1. n=eval(input())
  2. def find_su(num):
  3. ans=[]
  4. for i in range(2,num+1):#因数可以是大于其平方根的,不重复
  5. if num%i==0:
  6. ans.append(i)
  7. while num%i==0:
  8. num//=i
  9. return ans
  10. def phi(num):
  11. su=find_su(num)
  12. ans=num
  13. for i in su:
  14. ans=ans*(i-1)/i
  15. return int(ans)
  16. print(phi(n))

十三.黑白无常

某寝室的同学们在学术完之后准备玩一个游戏:  游戏是这样的,每个人头上都被贴了一张白色或者黑色的纸,现在每个人都会说一句话“我看到x张白色纸条和y张黑色的纸条”,又已知每个头上贴着白色纸的人  说的是真话、每个头上贴着黑色纸的人说的是谎话,现在要求你判断哪些人头上贴着的是白色的纸条,如果无解输出“NoSolution.”;如果有多组解,  则把每个答案中贴白条的人的编号按照大小排列后组成一个数(比如第一个人和第三个人头上贴着的是白纸条,那么这个数就是13;如果第6、7、8个人都贴的  是白纸条,那么这个数就是678)输出最小的那个数(如果全部都是黑纸条也满足情况的话,那么输出0)

思路:二进制的位运算,

  1. def numPrint(num):#将二进制数打印出来
  2. if num==0:
  3. print(0)
  4. return
  5. temp=0
  6. while num:
  7. temp+=1
  8. if num&1:
  9. print(temp,end='')
  10. num>>=1
  11. def CalLen(num):#计算出二进制数中1的个数
  12. ans=0
  13. while num:
  14. if num&1:
  15. ans+=1
  16. num>>=1
  17. return ans
  18. n=int(input().strip())
  19. nums=[list(map(int,input().strip().split())) for i in range(n)]
  20. N=1<<n#计算出总的状态数量
  21. ansFlag=False
  22. for i in range(N):
  23. flag=-2#定义初始值为-2,因为-1防止与无人说实话+1后==0冲突
  24. length=CalLen(i)
  25. for j in range(n):
  26. temp=1<<j
  27. if temp&i:
  28. if flag==-2:
  29. flag=nums[j][0]
  30. else:
  31. if flag!=nums[j][0]:
  32. flag=-3
  33. break
  34. else:
  35. if nums[j][0]==length:
  36. flag=-3#定义为-3防止与无人说实话的-2冲突,这是绝对不正确的情况
  37. break
  38. if flag==-2:#如果没有人说实话
  39. flag+=1
  40. if flag+1==length:#如果说实话的人的数量等于白色的数量
  41. ansFlag=True
  42. numPrint(i)
  43. break
  44. if not ansFlag:
  45. print("NoSolution.")

十四.盾神与砝码称重

有一天,他在宿舍里无意中发现了一个天平!这  个天平很奇怪,有n个完好的砝码,但是没有游码。盾神为他的发现兴奋不已!于是他准备去称一称自己的东西。他准备好了m种物品去称。神奇的是,盾神一早就  知道这m种物品的重量,他现在是想看看这个天平能不能称出这些物品出来。但是盾神稍微想了1秒钟以后就觉得这个问题太无聊了,于是就丢给了你。
思路:dfs,对于每一块砝码有三种情况:不用,和物品放一边,放物品对面的一边,可以利用这个来进行深度搜索,如果砝码的总重量都没有物品重则称不出来

  1. n,m=map(eval,input().split())
  2. fama=sorted(list(map(eval,input().strip().split())))
  3. goods=list(map(eval,input().strip().split()))
  4. def dfs(num,flag):
  5. if num==fama[flag]:
  6. return True
  7. if flag<n-1:
  8. if dfs(num-fama[flag],flag+1) or dfs(num+fama[flag],flag+1) or dfs(num,flag+1):
  9. return True
  10. return False
  11. for _ in range(m):
  12. igoods=goods[_]
  13. if igoods>sum(fama):
  14. print("NO")
  15. continue
  16. elif igoods==sum(fama):
  17. print("YES")
  18. continue
  19. else:
  20. if dfs(igoods,0):
  21. print("YES")
  22. else:
  23. print("NO")

十五.阶乘

一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积。阶乘的增长速度非常快,例如,13!就已经比较大了,已经无法存放在一个整型变量  中;而35!就更大了,它已经无法存放在一个浮点型变量中。因此,当n比较大时,去计算n!是非常困难的。幸运的是,在本题中,我们的任务不是去计算  n!,而是去计算n!最右边的那个非0的数字是多少。例如,5!  =  1*2*3*4*5  =  120,因此5!最右边的那个非0的数字是2。再如:7!  =  5040,因此7!最右边的那个非0的数字是4。请编写一个程序,输入一个整数n(n< =100),然后输出n!  最右边的那个非0的数字是多少。

思路:保留三位数字,再对数字相乘,如果末尾为0则舍弃,保留的位数不一定为3位,看输入数据的范围,保留位数越多答案越准确

  1. n=int(input())
  2. ans=1
  3. for i in range(1,n+1):
  4. ans*=i
  5. while ans%10==0:
  6. ans//=10
  7. ans%=1000 #为什么是1000?
  8. print(ans%10)

十六.机器人塔

X星球的机器人表演拉拉队有两种服装,A和B。
他们这次表演的是搭机器人塔。
类似:
     A
    B B
   A B A
  A A B B
 B B B A B
A B A B B A
队内的组塔规则是:
 A 只能站在 AA 或 BB 的肩上。
 B 只能站在 AB 或 BA 的肩上。
你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。
输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。
要求输出一个整数,表示可以产生的花样种数yi

思路:如果i+1行确定那么i行也确定,由此递推,只需要确定最后一行就可以,所以用位运算遍历状态,保留符合状态的结果,可以利用异或计算

  1. def Check(G):
  2. global N,n
  3. TempG=[[0 for ii in range(n)] for i in range(n)]
  4. for i in range(n):
  5. TempG[n-1][i]=G[i]
  6. for i in range(n-2,-1,-1):
  7. for j in range(i+1):
  8. TempG[i][j]=TempG[i+1][j]^TempG[i+1][j+1]
  9. if sum(map(sum,TempG))==N:#对二维列表求和
  10. return True
  11. return False
  12. M,N=map(int,input().strip().split())
  13. #若下一行确定则上一行也确定
  14. #首先计算出最底层的个数,枚举最底层的排列,若符合要求则答案加一
  15. #(1+n)*n/2=M+N -------> n^2+n-2M-2N=0 ------>n=(-1+(1+8M+8N)**0.5)/2
  16. n=int((-1+(1+8*M+8*N)**0.5)//2)
  17. print(n)
  18. #A为0 B为1
  19. ans=0
  20. for i in range(1<<n):
  21. G=[0 for _ in range(n)]
  22. for j in range(n):
  23. if 1<<j & i:
  24. G[j]=1
  25. if Check(G):
  26. ans+=1
  27. print(ans)

十七.传球游戏

游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。
聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球的方法被视作不同的方  法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方  式有1-> 2-> 3-> 1和1-> 3-> 2-> 1,共2种。

首先看我最先写的dfs算法,结果毫无疑问超时:

  1. n,m=map(int,input().strip().split())
  2. ans=0
  3. def dfs(times,val):
  4. global n,m,ans
  5. if min(n-val,val)>m-times:
  6. return
  7. if times==m and val==0:
  8. ans+=1
  9. return
  10. dfs(times+1,(val-1+n)%n)
  11. dfs(times+1,(val+1)%n)
  12. dfs(0,0)
  13. print(ans)

改进后的动态规划算法:

  1. n,m=map(int,input().strip().split())
  2. G=[[0 for i in range(n)]for j in range(m)]
  3. G[0][1]=1
  4. G[0][n-1]=1
  5. for i in range(1,m):
  6. for j in range(n):
  7. G[i][j]=G[i-1][(j+n-1)%n]+G[i-1][(j+1)%n]
  8. print(G[m-1][0])

十八.机器人繁殖

X星系的机器人可以自动复制自己。它们用1年的时间可以复制出2个自己,然后就失去复制能力。
每年X星系都会选出1个新出生的机器人发往太空。也就是说,如果X星系原有机器人5个,
1年后总数是:5 + 9 = 14
2年后总数是:5 + 9 + 17 = 31
如果已经探测经过n年后的机器人总数s,你能算出最初有多少机器人吗?

思路:找规律

  1. n,s=map(int,input().strip().split())
  2. x1=(1<<(n+1))-1
  3. x2=0
  4. for i in range(1,n+1):
  5. x2+=(1<<i)-1 #记得加括号
  6. print(int((s+x2)//x1))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/431243
推荐阅读
相关标签
  

闽ICP备14008679号