计算机导论课作业 09 (基于Python)

2 同计算机导论实例4-3“绘制一个半径为r的圆”,请利用小乌龟绘画出任意k的正k边形。

from turtle import *
import math
def jumpto(x,y):
    up();goto(x,y);down()
def step(r,k):
    S = math.radians(90*(1-2/k))
    return ((2*r)/math.tan(S))
def draw(x,y,r,k):
    S = step(r,k)
    speed(1000);jumpto(x,y)
    for i in range(k):
        forward(S)
        left(360/k)
    

draw(0,0,50,30)
s=Screen()
s.exitonclick()

from turtle import *
reset()
k=int(input())
for i in range(k):
    forward(720/k)
    left(360/k)
s=Screen()
s.exitonclick()

3、 (10 points)小乌龟程序练习题4.8.1

from turtle import *
for i in range(5):
    forward(100)
    right(180-36)
s=Screen()
s.exitonclick()

4、 (10 points)小乌龟程序练习题4.8.2

from turtle import *
def jumpto(x,y):
    up()
    goto(x,y)
    down()
speed(2000)
for i in  range(4):
    jumpto(0,-20*i)
    circle(50+20*i)
for i in range(0,90,6):
    jumpto(0,50)
    left(i)
    for j in range(4):
        forward(100)
        left(90)

    

S=Screen()
S.	exitonclick(

注意对于找假币问题,我们假设只有一个天平,天平两端放钱币(可以任意多个)后,天平可以知道哪边比较重或轻。你可以调用两个sum()值的比较来“模拟”天平。注意你没有一个“秤”能得出钱币的实际重量,你只能利用天平得出两堆钱币的相对重量轻重。
5、 (每题6 points)练习题5.1.1, 5.1.2, 5.1.3, 5.1.5

#练习题5.1.1,

import random
L=[]
n = int(input())
fake = random.randint(0,n-1)
for i in range(n):
    L.append(3)
L[fake]=2
print(L)
for i in range(len(L)-1):
    if L[i]==L[i+1]:
        continue
    elif L[i]>L[i+1]:
        print(i+2)
        break
else:print(i+1);break

#5.1.2, 

import random
L=[]
n = int(input())
fake = random.randint(0,n-1)
for i in range(n):
    L.append(3)
L[fake]=2
#L=[3,3,3,3,3,2,3,3,3,3,3]
print(L)

if len(L) <= 1:
    print("硬币太少")
    
else:
    x=len(L)
    y = 0
    L1 = L[:x//2]
    L2 = L[x//2:x//2*2]
    
    while(len(L1)>1):
        K1 = sum(L1)
        K2 = sum(L2)
        #print(K1," ",K2)
        if(K1 == K2):
            print("假币是第%d枚"%(x+y))
            break
        elif(K1>K2):#从右边找
            x//=2
            y+=x
            L1 = L2[:x//2]
            L2 = L2[x//2:x//2*2]
            #print(L1," ",L2)
            #print(x," ",y)
        elif(K2>K1):
            x//=2
            L2 = L1[x//2:x//2*2]
            L1 = L1[:x//2]
            #print(L1," ",L2)
            #print(x," ",y)

    if(len(L1)==1):
        if L1[0]>L2[0]:
            print("假币是第%d枚"%(2+y))
        elif L1[0]<L2[0]:
            print("假币是第%d枚"%(1+y))
        else:
            
            print("假币是第%d枚"%(3+y))

#5.1.3,

def findcoin(a,L):
    x=len(L)
    print(a,L)
    if(x==1):return(a)
    if x%2:
        x-=1
        y=1
    else:y=0
    if(sum(L[:x//2])<sum(L[x//2:x])):
        return(findcoin(a,L[:x//2]))
    elif(sum(L[:x//2])>sum(L[x//2:x])):
        return(findcoin(a+x//2,L[x//2:x]))
    else:
        if (y==0):return(-1)
        else:
            if(L[x]<L[0]):return(a+x)
            else:return(-1)
    
import random
L=[]
n = int(input())
fake = random.randint(0,n-1)
for i in range(n):
    L.append(3)
L[fake]=2
a=findcoin(0,L)
print(a+1)

5.1.5
方法一:逐个比较n-1次
方法二:三分法,分成三份,
如果有两份较轻,就从两份中继续三分法
如果只有一份轻,
那么就是三分法里面没放进去的一个硬币或者两个硬币中有假币
一个硬币不用比较,两个硬币比较一次可以得到,剩下在那一份轻的硬币中继续三分法

如果三份质量相同,那就是没有进行比较的两个银币均为假币

6、 (10 points)练习题 5.1.7,编程。

Q=[[0,0],[0,0]]
import random
L=[]
n = int(input())
fake = random.randint(0,n-1)
rand = random.random()
for i in range(n):
    L.append(3)
if rand > 0.5:
    L[fake]+=1
else:
    L[fake]-=1
print(L)

Q[0][0]=L[0]
Q[0][1]+=1

for i in range(1,len(L)):
    if Q[0][0]==L[i]:
        Q[0][1]+=1
    else:
        Q[1][0]=L[i]
        Q[1][1]+=1
    print(Q)
    if (Q[0][1] == 1 and Q[1][1]>=2):
        a=(Q[0][1]+Q[1][1])
        print("第%d枚硬币是假币"%a)
        break
    elif(Q[1][1] == 1 and Q[0][1]>=2):
        a=(Q[0][1]+Q[1][1])
        print("第%d枚硬币是假币"%a)
        Break

7、 (10 points)改写Hanoi 程序, 假设A杆起初有n个圆盘, 从小到大编号为1,2,…, n,请打印出每次移动后A, B, C上的圆盘编号从小到大有哪些。请试验n=4. 这题可以与一位同学合作。

count=1
def main():
    n=int(input("盘子个数"))
    A=[['A'],[]];B=[['B'],[]];C=[['C'],[]]
    for i in range(n,0,-1):
        A[1].append(i)
    Hanoi(n,A,B,C)



def Hanoi(n,A,B,C):
    global count
    
    
    if n == 1:
        print("%d %s->%s"%(count,A[0][0],C[0][0]))
        C[1].append(A[1].pop())
        print(A[0][0],A[1],B[0][0],B[1],C[0][0],C[1])
        count+=1
    elif n > 1:
        Hanoi(n-1,A,C,B)
        Hanoi(1,A,B,C)
        Hanoi(n-1,B,A,C)

if __name__=="__main__":
main()

8、 (10 points) 编程导论 习题4.1

List=[1,2,3,4,12,45,6,0]
def min_max(List,L,R):
    if (R-L)==1:
        if List[L]<List[R]:
            
            return List[L],List[R]
        else:
            return List[R],List[L]
    if L==R:
        return List[L],List[L]
    if L>R:
        return [],[]
    mid = (L + R) // 2
    min1,max1 = min_max(List,mid,R)
    min2,max2 = min_max(List,L,mid)
    if min1<min2:
        MIN = min1
    else:
        MIN = min2
    if max1>max2:
        Max = max1
    else:
        Max = max2
    return MIN,Max

MIN,MAX=min_max(List,0,len(List)-1)
print(MIN," ",MAX)

9、 (10 points) 编程导论 习题4.2

L=[1,2,3,4,5]

time = 0

def ave(L,n):
    if len(L)==1:
        return L[0]
    return (L[0]+ave(L[1:],n-1)*(n-1))/n

a = ave(L,len(L))
print(a)

10、 (12 points)给定一个整数列表L输出一个列表S,其中S[i]=L[0]到L[i]的和。例如L=[1,2,4,2], 则输出S=[1,3,7,9]。用二种递归方式做Python编程。
A)用简单递归(不是二分法)方式实现此程序

L=[1,2,4,2]
def SUM(L):
    A = []
    if len(L) == 1:
        A+=[L[0]]
        return L[0],A
    else:
        num,K=SUM(L[:len(L)-1])
        num+=L[len(L)-1]
        K.append(num)
        return num,K
a,K = SUM(L)
print(a,K)

B) 再用二分递归方式来实现此程序。

L=[1,2,3,4,5,6,7,8]
def SUM(L):
    A = []
    if len(L) == 1:
        A+=[L[0]]
        return A
    else:
        A1 = SUM(L[:len(L)//2])
                 
        A2 = SUM(L[len(L)//2:])
        for i in range(len(A2)):
            A2[i]+=A1[len(A1)-1]
        A1 += A2
        return A1
K = SUM(L)
print(K)

11、 (8 points)计算机导论的程序练习题 5.3.2。 试验和解释。

def FA(a,b,c):
    carry = 0;sum = 0
    if (( a==1 and b == 1) or (b==1 and c == 1) or (a==1 and c ==1 )):
        carry = 1
    if(( a== 1 and b == 1 and c == 1)or(a==1 and b == 0 and c == 0)or(a==0 and b == 1 and c == 0) or (a==0 and b == 0 and c == 1)):
        sum = 1
    return carry,sum

def add_B(x,y,c=0):
    while(len(x)<len(y)):
        x = [0]+x
    while(len(x)>len(y)):
        y = [0]+y
    if len(x) == 1:
        ctemp ,stemp = FA(x[0],y[0],c)
        return(ctemp,[stemp])
    if len(x) == 0:
        return c,[]
    c1,s1 = add_B(x[len(x)//2:len(x)],y[len(y)//2:len(y)],c)
    c2,s2 = add_B(x[0:len(x)//2],y[0:len(y)//2],0)
    c3,s3 = add_B(x[0:len(x)//2],y[0:len(y)//2],1)
    if c1 == 0:
        return(c2,s2+s1)
    if c1 == 1:
        return(c3,s3+s1)


    
L1=[0,0,0,1,1,1]
L2=[1,1,1]

a,b=add_B(L1,L2,1)
b=[a]+b
while(b[0]==0):
    
    b=b[1:]
print(b)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值