educoder答案pythonnumpy_Educoder 题解

Solution

4.2:

第一关:

求个导发现有两个根,分别二分就行了

importnumpy as np

E= 1e-6

########## begin ###########请在此填写代码, 计算6*np.exp(x)-113*x+17=0的根

deff(x):return 6*np.exp(x)-113*x+17

defdivd(L,R):while(L

mid=(L+R)/2

if(abs(f(mid))<=E):returnmidif(f(mid)

R=midelse:

L=middefdiv(L,R):while(L

mid=(L+R)/2

if(abs(f(mid))<=E):returnmidif(f(mid)>-E):

R=midelse:

L=midprint("%.4f"%divd(0,1.0))print("%.4f"%div(4.0,5.0))########## end ##########

第二关:

不难发现h的值依赖于角度θ,且θ满足sinθ/θ=L/S,即S×sinθ/θ-L=0 对该式求导,发现其单减,且显然0

又因为有h=L/2*tan(θ/2),这样就做完了

from math import *L, n, C=map(float, input().split())

E=1e-8S=(1+n*C)*Ldefdivd(l,r):while(l

mid=(l+r)/2val=S*sin(mid)/mid-Lif(abs(val)<=E):returnmidif(val

r=midelse:

l=mid

t=divd(0,pi/2)

h=L/2*tan(t/2)########## begin ###########请在此填写代码,求方程的根

########## end ##########

print('%.4f' % h)

4.3:

第一关:

显然由某一个点出发的最小积依赖于由他下方点出发的最小积或右下方出发的最小积,取二者中的最小值

n =eval(input())

dp=[]for i inrange(n):

X=dp.append(list(map(int, input().split())))for i in range(n-2,0,-1):for j in range(0,i+1,1):

dp[i][j]*=min(dp[i+1][j+1],dp[i+1][j])

dp[0][0]*=min(dp[1][0],dp[1][1])print(dp[0][0]

第二关:

递归太麻烦了,for循坏可以O(n)搞完,效率更高还好写

dp[i]表示以i为起点的最大子序列积,有dp[i]=max(dp[i+1]×A[i],dp[i])(分别对应将A[i]加入以A[i+1]为起始的最大子序列或不加入单独考虑)

最末尾显然只能单独考虑,有dp[n-1]=A[n-1],倒序for一遍,再取最大的dp[i]即可

代码中把A列表和dp列表共用了,不影响正确性

n =eval(input())

A=list(map(float, input().split()))for i in range(n-2,0,-1):

A[i]=max(A[i],A[i+1]*A[i])

A[0]=max(A[0],A[1]*A[0])

ans=0.0

for i in range(0,n,1):

ans=max(ans,A[i])print("%.2f"%(ans)

4.4:

第一题的话,考虑归并,先二分再合并,合并时注意两个子点集之间的配对情况

第二题,实际上和第一题一样,只不过处理的时候注意一下两个点的分组情况,只有不同组的时候才需要处理

第一关:

from math import *n=eval(input())

A=[]for i inrange(n):

x,y=map(int, input().split())

A.append((x,y))defDistance(a, b):return sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)#求[low..high]区间内的最小点距

defFidMin(A,L,R):########## begin ##########

#请在此填写代码,返回区间[low,high]的最小点距

mid=(L+R)//2

if(L==R):return 1e9

if(L==R-1):returnDistance(A[L],A[R])

d=min(FidMin(A,L,mid),FidMin(A,mid+1,R))

tmp=[]

p0=A[mid]for i in range(L,R+1,1):

p1=A[i]if(abs(p1[0]-p0[0])=d):breakd=min(d,Distance(tmp[i],tmp[j]))returnd########## end ##########

A.sort()

result=FidMin(A,0,len(A)-1)print('%.3f' % result)

View Code

第二关:

importmath

n=eval(input())

A=[]for i in range(n*2):

group= 1 if i

A.append((x,y,group))defDistance(a, b):return math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)#求[low..high]区间内的最小点距

defFidMin(A,L,R):########## begin ##########

#请在此填写代码,返回区间[low,high]的最小点距,且这两点属于不同的组

mid=(L+R)//2

if(L==R):return 1e9

if((L==R-1) and (A[L][2]==A[R][2])):return 1e9

if(L==R-1):returnDistance(A[L],A[R])

d=min(FidMin(A,L,mid),FidMin(A,mid+1,R))

tmp=[]

p0=A[mid]for i in range(L,R+1,1):

p1=A[i]if(abs(p1[0]-p0[0])

tmp.append(p1)

tmp.sort(key=lambda x:x[1])

upp=len(tmp)-1

for i in range(0,upp+1,1):for j in range(i+1,upp+1,1):if(abs(tmp[i][1]-tmp[j][1])>=d):break

if(tmp[i][2]!=tmp[j][2]):

d=min(d,Distance(tmp[i],tmp[j]))returnd########## end ##########

A.sort()

result=FidMin(A,0,len(A)-1)print('%.3f' % result)

View Code

4.5:

第一关:

递归就行了,先序遍历,每访问一个点答案+1

defCalcNodes(tree):########## begin ##########

#请在此填写代码

if(len(tree)==0):return0return 1+CalcNodes(tree[1])+CalcNodes(tree[2])########## end ##########

View Code

第二关:

中序中,根节点所在位置左边的序列就是左子树的中序序列,右边就是右子树的中序序列

然后先序序列其实就是根+左子树的先序序列+右子树的先序序列

后序序列是左子树后序+右子树后序+根

#pre_order:先根序列 in_order:中根序列#要求返回后跟序列

defget_postorder(pre_order, in_order):########## begin ##########

#请在此填写代码

l=len(in_order)if(l==0):return ''root=pre_order[0]if(l==1):returnrootfor i in range(0,l,1):if(in_order[i]==root):

pos=ibreakpol=''por=''iol=''ior=''

for i in range(1,1+pos,1):

pol=pol+pre_order[i]for i in range(1+pos,l,1):

por=por+pre_order[i]for i in range(0,pos,1):

iol=iol+in_order[i]for i in range(pos+1,l,1):

ior=ior+in_order[i]

p1=get_postorder(por,ior)

p2=get_postorder(pol,iol)return p2+p1+root########## end ##########

View Code

4.6:

第一关:

由于本题我们只关心序列的合法性,对于左括号,入栈,对于右括号,不必入栈,只需要与栈顶的左括号相匹配,匹配成功就继续处理下一个括号,失败就直接输出false

全部括号都处理完成后,如果栈内仍有未匹配的左括号,还是输出false

在处理过程中,记得留意空栈的情况

from queue importLifoQueue#括号匹配

S=input() #输入的字符串

sta=[]########## begin ###########请在此填写代码

tot=0

ans=Truedefmatch(x,y):if(x=='[' and y==']'):returnTrueif(x=='(' and y==')'):returnTrueif(x=='{' and y=='}'):returnTruereturnFalsefor i inS:if(i=='[' or i=='(' or i=='{'):

sta.append(i)

tot+=1

else:if(tot==0):

ans=Falsebreak

if(match(sta[tot-1],i)):del sta[tot-1]

tot-=1

else:

ans=Falsebreak

if(tot!=0):

ans=Falseprint(ans)

View Code

第二关:

与上一关有些不同,栈里维护的是括号在原字符串的索引而不是括号本身

新增一个ok列表,ok[i]表示第i位的括号是否匹配成功,ok[i]=1表示成功,ok[i]=0则是失败

匹配方法则与第一关类似,但因为需要计数,所以这里右括号也要入栈

最开始ok[i]均设为0,匹配成功,把这组左右括号对应的ok[i]改为1

答案就是ok[i]列表中最长的连续为1的子段的长度

复杂度O(n)

from queue importLifoQueue#括号匹配

S=input() #输入的字符串

sta=[]

ok=[]########## begin ###########请在此填写代码

tot=0

ans=0

cnt=0defmatch(x,y):if(x=='[' and y==']'):returnTrueif(x=='(' and y==')'):returnTrueif(x=='{' and y=='}'):returnTruereturnFalse

l=len(S)for i in range(0,l,1):

ok.append(0);for i in range(0,l,1):if(S[i]=='[' or S[i]=='(' or S[i]=='{'):

sta.append(i)

tot+=1

else:if(tot==0):

sta.append(i)

tot+=1

elif(match(S[sta[tot-1]],S[i])):

ok[i]=1ok[sta[tot-1]]=1

del sta[tot-1]

tot-=1

else:

sta.append(i)

tot+=1

for i in range(0,l,1):if(ok[i]==1):

cnt+=1ans=max(ans,cnt)else:

cnt=0print(ans)

View Code

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值