赞
踩
最近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的完整表达式,以方便奶牛们做题。
思路:简单的递归函数,要注意断点处的值
- def ann(n,s):
- if n%2==1:
- ans='sin('+str(n)+'-'+s+')'
- else:
- ans = 'sin(' + str(n) + '+' + s + ')'
- if n==1:
- return ans
- else:
- return ann(n-1,ans)
- def an(n,s):
- s='sin('+str(n)+')'
- if n==1:
- return s
- return ann(n-1,s)
- def sn(n,s):
- global N
- if n==N:
- return s+an(n,'')+'+'+str(1)
- else:
- s='('+s+an(n,'')+'+'+str(N-n+1)+')'
- return sn(n+1,s)
-
- N=eval(input())
-
- print(sn(1,''))
平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。
思路:先分别计算出长和宽相交的长度,再相乘计算出面积,注意要考虑重合时的多种情况
- a=list(map(eval,input().strip().split()))
- b=list(map(eval,input().strip().split()))
- def cha(c,d,e,f):
- #判断相交关系
- if e>=c and e<=d:
- return min(d,f)-e
- if f>=c and f<=d:
- return f-max(c,e)
- #判断包含关系
- if e<=c and f>=d:
- return d-c
- if c<=e and d>=f:
- return f-e
- return 0
- 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()
- 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'}
- a,b=map(int,input().strip().split())
- if a<=20:
- print(num[a],end=' ')
- else:
- print(num[20],num[a%20],end=' ')
- if b==0:
- print("o'clock")
- elif b<=20:
- print(num[b])
- else:
- n=[0,0,'twenty','thirty','forty','fifty']
- if b%10==0:
-
- print(n[b//10])
- else:
- 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'的问题.
- def readnum(n):
- ans=''
- global num_list
- if n//1000>0:
- ans+=str(num_list[n//1000])+' qian '
- n%=1000
- if n//100>0:
- ans+=str(num_list[n//100])+' bai '
- n %= 100
- if n // 10 > 0:
- ans +=str(num_list[n // 10]) + ' shi '
- if n % 10 > 0:
- ans +=str(num_list[n % 10])
- else:
- if n % 10 > 0:
- ans += 'ling ' + str(num_list[n % 10])
- else:
- n%=100
- if n//10>0:
- ans+='ling '+str(num_list[n//10])+' shi '
- if n%10>0:
- ans+=str(num_list[n%10])
- else:
- if n%10>0:
- ans+='ling '+str(num_list[n%10])
- else:
- if n//100>0:
- ans+=str(num_list[n//100])+' bai '
- n %= 100
- if n // 10 > 0:
- ans +=str(num_list[n // 10]) + ' shi '
- if n % 10 > 0:
- ans +=str(num_list[n % 10])
- else:
- if n % 10 > 0:
- ans += ' ling ' + str(num_list[n % 10])
- else:
- n%=100
- if n//10>0:
- if n//10==1:
- ans+='shi '
- else:
- ans+=str(num_list[n//10])+' shi '
- if n % 10 > 0:
- ans += str(num_list[n % 10])
- else:
- if n%10>0:
- ans+=str(num_list[n%10])
- return ans.strip()
- num=eval(input().strip())
- num_list=['ling','yi','er','san','si','wu','liu','qi','ba','jiu','shi']
- ans=''
- if num//100000000>0:
- a=num//100000000
- ans+=readnum(a)+' yi '
- num%=100000000
- if num//10000>0:
- if len(ans)>1 and ans[-2]=='i' and num//10000000==0:
- ans+='ling '
- a=num//10000
- ans+=readnum(a)+' wan '
- num%=10000
- if num>0:
- if len(ans)>1 and ans[-2] in ['i','n'] and num//1000==0:
- ans+='ling '
- ans+=readnum(num)
- 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数组剩余的元素也要输出
- nm=input()
- a=list(map(eval,input().strip().split()))
- b=list(map(eval,input().strip().split()))
- m,n=map(eval,input().split())
- ans=[]
- for i in range(m):
- ans.append(a[i])
- for i in range(n):
- ans.append(b[i])
- if len(ans)<len(a):
- for i in range(len(ans),len(a)):
- ans.append(a[i])
- for i in range(len(ans)-1):
- print(ans[i],end=',')
- print(ans[len(ans)-1])
小朋友排成一排,老师给他们分苹果。
小朋友从左到右标号1..N。有M个老师,每次第i个老师会给第Li个到第Ri个,一共Ri-Li+1个小朋友每人发Ci个苹果。
最后老师想知道每个小朋友有多少苹果。
思路:在一个区间上将数做加减法时利用差分数组,直接简化为在端点进行加减法.
- from collections import defaultdict
- N,M=map(eval,input().split())
- d=defaultdict(int)
- for i in range(M):
- l,r,c=map(int,input().split())
- d[l]+=c
- d[r+1]-=c
- ans=0
- for i in range(1,N+1):
- ans+=d[i]
- 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算法求出连通块,再根据输入的数字算出答案
- n,k=map(int,input().split())
- m=[[float('inf') for i in range(10)]for j in range(10)]
- for i in range(10):
- m[i][i]=1
- for i in range(k):
- a,b=map(int,input().split())
- m[a][b]=1
- for k in range(10):
- for i in range(10):
- for j in range(10):
- m[i][j]=min(m[i][j],m[i][k]+m[k][j])
- c=[0 for i in range(10)]
- for i in range(10):
- for j in range(10):
- if m[i][j]<float('inf'):
- c[i]+=1
- ans=1
- while n:
- ans*=c[n%10]
- n//=10
- print(ans)
研究表明,这种传染病的传播具有两种很特殊的性质;
第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不得病,或者是XY之间的传播途径被切断,则X就不会得病。
第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一代患者,而不会再传播给下一代。
这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中 心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也 就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个 切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。
思路:先用链表保存输入的连接关系,之后再将他们构造成一棵树,这样可以减少复杂度,再使用dfs寻找最少的感染人数
-
- n,p=map(int,input().split())
- linklist=[[] for i in range(n+1)]
- for i in range(p):
- a,b=map(int,input().split())
- linklist[a].append(b)
- linklist[b].append(a)
- tree=[[] for i in range(n+1)]
- def createTree(num):
- global tree,linklist
- if len(linklist[num])==0:
- return
- else:
- tree[num]=linklist[num][:]
- for i in linklist[num]:
- linklist[i].remove(num)
- createTree(i)
- return
- createTree(1)
- ans=300
- def dfs(curFloor,curans):
- global ans,tree
- nextFloor=[]
- minans=300
- for i in curFloor:
- nextFloor+=tree[i]
- if nextFloor==[]:
- if curans<ans:
- ans=curans
- return 0
- elif len(nextFloor)-1+curans<=ans:
- for i,x in enumerate(nextFloor):
- del nextFloor[i]
- nextans=dfs(nextFloor,curans+len(nextFloor)-1)
- if minans>nextans:
- minans=nextans
- nextFloor.insert(i,x)
- return len(nextFloor)-1+minans
- else:
- return 300
-
- 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高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
思路:拓扑排序问题
- num=set()
- linklist=[[] for i in range(26)]
- while True:
- try:
- a,b=input().split('>')
- num.add(ord(a)-ord('A'))
- num.add(ord(b)-ord('A'))
- linklist[ord(a)-ord('A')].append(ord(b)-ord('A'))
- except:
- break
- GT=[[0 for i in range(26)]for j in range(26)]
- for i in range(26):
- for j in linklist[i]:
- GT[j][i]=1
- ans=''
- while len(num):
- flag=True
- for i in range(26):
- if i in num and sum(GT[i])==0:
- ans+=chr(i+ord('A'))
- num.remove(i)
- for j in linklist[i]:
- GT[j][i]=0
- flag=False
- if flag:
- ans='No Answer!'
- break
- print(ans)
输入一个自然数n,求小于等于n的素数之和
思路:素数筛模板
- n=int(input())
- ai=[0 for i in range(n+1)]
- for i in range(2,int(n**0.5)+2):
- if ai[i]==0:
- for j in range(i*i,n+1,i):
- ai[j]=1
- ans=0
- for i in range(2,n+1):
- if ai[i]==0:
- ans+=i
- print(ans)
程序提示用户输入三个字符,每个字符取值范围是0-9,A-F。然后程序会把这三个字符转化为相应的十六进制整数,并分别以十六进制,十进制,八进制输出。
-
- s=input().lstrip('0')
- s=s.strip()
- ans=[]
- if len(s)==0:
- s='0'
- ans.append(s)
- d=dict()
- d['A']=10
- d['B']=11
- d['C']=12
- d['D']=13
- d['E']=14
- d['F']=15
- f10=0
- for i in s:
- try:
- f10=f10*16+int(i)
- except:
- f10=f10*16+d[i]
- ans.append(str(f10))
- f8=''
- while f10:
- f8+=str(f10%8)
- f10//=8
- if len(f8)==0:
- f8='0'
- ans.append(f8[::-1])
- s=' '.join(ans)
- 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类型上界,可通过调整公式各项的计算顺序避免(比如先做除法)!
- n=eval(input())
- def find_su(num):
- ans=[]
- for i in range(2,num+1):#因数可以是大于其平方根的,不重复
- if num%i==0:
- ans.append(i)
- while num%i==0:
- num//=i
- return ans
- def phi(num):
- su=find_su(num)
- ans=num
- for i in su:
- ans=ans*(i-1)/i
- return int(ans)
- print(phi(n))
某寝室的同学们在学术完之后准备玩一个游戏: 游戏是这样的,每个人头上都被贴了一张白色或者黑色的纸,现在每个人都会说一句话“我看到x张白色纸条和y张黑色的纸条”,又已知每个头上贴着白色纸的人 说的是真话、每个头上贴着黑色纸的人说的是谎话,现在要求你判断哪些人头上贴着的是白色的纸条,如果无解输出“NoSolution.”;如果有多组解, 则把每个答案中贴白条的人的编号按照大小排列后组成一个数(比如第一个人和第三个人头上贴着的是白纸条,那么这个数就是13;如果第6、7、8个人都贴的 是白纸条,那么这个数就是678)输出最小的那个数(如果全部都是黑纸条也满足情况的话,那么输出0)
思路:二进制的位运算,
- def numPrint(num):#将二进制数打印出来
- if num==0:
- print(0)
- return
- temp=0
- while num:
- temp+=1
- if num&1:
- print(temp,end='')
- num>>=1
- def CalLen(num):#计算出二进制数中1的个数
- ans=0
- while num:
- if num&1:
- ans+=1
- num>>=1
- return ans
- n=int(input().strip())
- nums=[list(map(int,input().strip().split())) for i in range(n)]
- N=1<<n#计算出总的状态数量
- ansFlag=False
- for i in range(N):
- flag=-2#定义初始值为-2,因为-1防止与无人说实话+1后==0冲突
- length=CalLen(i)
- for j in range(n):
- temp=1<<j
- if temp&i:
- if flag==-2:
- flag=nums[j][0]
- else:
- if flag!=nums[j][0]:
- flag=-3
- break
- else:
- if nums[j][0]==length:
- flag=-3#定义为-3防止与无人说实话的-2冲突,这是绝对不正确的情况
- break
- if flag==-2:#如果没有人说实话
- flag+=1
-
- if flag+1==length:#如果说实话的人的数量等于白色的数量
- ansFlag=True
- numPrint(i)
- break
- if not ansFlag:
- print("NoSolution.")
有一天,他在宿舍里无意中发现了一个天平!这 个天平很奇怪,有n个完好的砝码,但是没有游码。盾神为他的发现兴奋不已!于是他准备去称一称自己的东西。他准备好了m种物品去称。神奇的是,盾神一早就 知道这m种物品的重量,他现在是想看看这个天平能不能称出这些物品出来。但是盾神稍微想了1秒钟以后就觉得这个问题太无聊了,于是就丢给了你。
思路:dfs,对于每一块砝码有三种情况:不用,和物品放一边,放物品对面的一边,可以利用这个来进行深度搜索,如果砝码的总重量都没有物品重则称不出来
- n,m=map(eval,input().split())
- fama=sorted(list(map(eval,input().strip().split())))
- goods=list(map(eval,input().strip().split()))
- def dfs(num,flag):
- if num==fama[flag]:
- return True
- if flag<n-1:
- if dfs(num-fama[flag],flag+1) or dfs(num+fama[flag],flag+1) or dfs(num,flag+1):
- return True
- return False
-
- for _ in range(m):
- igoods=goods[_]
- if igoods>sum(fama):
- print("NO")
- continue
- elif igoods==sum(fama):
- print("YES")
- continue
- else:
- if dfs(igoods,0):
- print("YES")
- else:
- 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位,看输入数据的范围,保留位数越多答案越准确
- n=int(input())
- ans=1
- for i in range(1,n+1):
- ans*=i
- while ans%10==0:
- ans//=10
- ans%=1000 #为什么是1000?
- 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行也确定,由此递推,只需要确定最后一行就可以,所以用位运算遍历状态,保留符合状态的结果,可以利用异或计算
- def Check(G):
- global N,n
- TempG=[[0 for ii in range(n)] for i in range(n)]
- for i in range(n):
- TempG[n-1][i]=G[i]
- for i in range(n-2,-1,-1):
- for j in range(i+1):
- TempG[i][j]=TempG[i+1][j]^TempG[i+1][j+1]
- if sum(map(sum,TempG))==N:#对二维列表求和
- return True
- return False
- M,N=map(int,input().strip().split())
- #若下一行确定则上一行也确定
- #首先计算出最底层的个数,枚举最底层的排列,若符合要求则答案加一
- #(1+n)*n/2=M+N -------> n^2+n-2M-2N=0 ------>n=(-1+(1+8M+8N)**0.5)/2
- n=int((-1+(1+8*M+8*N)**0.5)//2)
- print(n)
- #A为0 B为1
- ans=0
- for i in range(1<<n):
- G=[0 for _ in range(n)]
- for j in range(n):
- if 1<<j & i:
- G[j]=1
- if Check(G):
- ans+=1
- print(ans)
游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。
聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球的方法被视作不同的方 法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方 式有1-> 2-> 3-> 1和1-> 3-> 2-> 1,共2种。
首先看我最先写的dfs算法,结果毫无疑问超时:
- n,m=map(int,input().strip().split())
- ans=0
- def dfs(times,val):
- global n,m,ans
- if min(n-val,val)>m-times:
- return
- if times==m and val==0:
- ans+=1
- return
- dfs(times+1,(val-1+n)%n)
- dfs(times+1,(val+1)%n)
- dfs(0,0)
- print(ans)
-
改进后的动态规划算法:
- n,m=map(int,input().strip().split())
- G=[[0 for i in range(n)]for j in range(m)]
- G[0][1]=1
- G[0][n-1]=1
- for i in range(1,m):
- for j in range(n):
- G[i][j]=G[i-1][(j+n-1)%n]+G[i-1][(j+1)%n]
- print(G[m-1][0])
-
X星系的机器人可以自动复制自己。它们用1年的时间可以复制出2个自己,然后就失去复制能力。
每年X星系都会选出1个新出生的机器人发往太空。也就是说,如果X星系原有机器人5个,
1年后总数是:5 + 9 = 14
2年后总数是:5 + 9 + 17 = 31
如果已经探测经过n年后的机器人总数s,你能算出最初有多少机器人吗?
思路:找规律
- n,s=map(int,input().strip().split())
- x1=(1<<(n+1))-1
- x2=0
- for i in range(1,n+1):
- x2+=(1<<i)-1 #记得加括号
- print(int((s+x2)//x1))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。