1、(10 points)《计算机导论》1.5.4,完成求圆周率-蒙特卡洛法的Python程序,试验不同的times值。试试看10的9次方。
思路:利用解析几何中单位圆的几何意义来构造出单位圆四分之一的点集,利用多次迭代使落在圆内的点比上1*1正方形的面积近似于pi/4,最后将得到的概率乘以4即可近似得到pi的大小
import random
def pi(times):
sum = 0
for i in range(times):
x = random.random()
y = random.random()
d2 = x*x+y*y
if d2 <= 1: sum+=1
return(sum/times*4)
times=1e10
x=pi(int(times))
print("Pi=%.8f"%(x))
3、(10 points)请写一个Python程序,利用双层循环完成以下的输出:
******
-*****
–****
—***
----**
-----*
------
第一行打印出6个星号,第二行打印出一个“-”和5个星号,依此类推,到第7行时打印出6个“-”。必须要用双层循环,在内层会有两个循环。
a=int(input("please import a number: \n"))
for i in range(1,a+2):
for j in range(1,i):
print("_",end="")
for j in range(a+1,i,-1):
print("*",end="")
print("\n")
4、(10 points)《编程导论》练习题2.1.2 和 2.1.3。
思路1:题目要求循环体内无法使用乘法,我们可以换个思路考虑,不能用乘法但是可以用除法啊!!!
思路2:不在循环体内用乘法就在循环体外用吧,内部用加法代替乘法
#2.1.2
#(1)
x=0;y=0;b=2
for i in range(0,10):
if x == 0:
y = b
print("y = ",y,"x = ",x)
x += 0.5
else:
y = 7.378/(1/x)+b
print("y = ",y,"x = ",x)
x += 0.5
#(2)
y=2;x=0;a=7.378*0.5
for i in range(1,10):
y += a
x += 0.5
print("y = ",y,"x = ",x)
2.1.3
思路:既然用幂函数运算比较耗时不如用pow函数
a0 = 2
n = int(input("please import a number: \n"))
p = 2
x = 0
for i in range(0,n):
x += a0 * pow(p,i)
print("the sum of product is ",x)
5、(10 points)(A)完成《编程导论》2.1.2节的第二种方法和第三种方法的Python程序。(B)请问当L=[1,2,3,4,5,6,7,8] 和 L=[8,7,6,5,4,3,2,1] 时这二种方法所需要的比较次数各是多少?
#方法2
L = [12,31,45,79,22]
MIN = MAX =L[0]
for i in range(1,len(L)):
if MIN>L[i]:MIN = L[i]
elif MAX<L[i]:MAX = L[i]
print(MAX)
print(MIN)
#方法3
方法3
L = [12,31,45,79,22]
if L[0]>L[1]:min=L[1];max=L[0]
else: max = L[1]; min = L[0]
for i in range(2,len(L)-1,2):
if L[i] > L[i+1]:
if min > L[i+1]:min = L[i+1]
if max < L[i]:max = L[i]
else:
if min > L[i]:min = L[i]
if max < L[i+1]:max=L[i+1]
if len(L)%2 != 0:
if min > L[len(L)-1]:min = L[len(L)-1]
elif max < L[len(L)-1]:max = L[len(L)-1]
print(max,"\n",min)
L=【1,2,3,4,5,6,7,8】
第二种方法 14次
第三种方法 7次
L=【8,7,6,5,4,3,2,1】
第二种方法 7次
第三种方法 7次
6、(10 points)《编程导论》练习题2.1.4,假设x=1, y=1, 找出是否有数列元素是11的倍数也是13的倍数,打印出此数。(请注意沙老师出题时也不知道有没有这个数!所以沙老师也很好奇你的答案。)
x = int(input("please enter x as the first number \n"))
y = int(input("please enter y as the second number \n"))
a = int(input("The first common factor of the aiming number is \n"))
b = int(input("The second common factor of the aiming number is \n"))
L=[]#该程序未判定输入的第一第二项是否符合同除的条件
L.append(x)#由于修改的代码多于目前已写的代码量,且考虑到一般情况,故此处不判断第一第二项
L.append(y)
while(1):
z = x + y
x = y
y = z
L.append(z)
if(z % a == 0):
if(z % b == 0):
break
print(L)
7、(10 points)《编程导论》练习题2.5.1,(A)完成及试验书中二分法的Python程序,(B)请解释为什么二分查找的前提是所搜寻的列表为排好序的列表?假设列表长度为100000,请问用二分查找法最多找几次能知道答案?(C)你能用递归函数的方式来完成此二分查找吗?
#A
def binary_search(L,a):
min = 0
max = len(L) - 1
mid = (max + min) //2
while not(L[mid] == a) and (min <= max):
if L[mid] < a:
min = mid + 1
else:
max = mid - 1
mid = (min + max) // 2
if L[mid] == a:
return mid
else:return -1
L = [1,2,3,4]
a = binary_search(L,99)
print(a)
#C
def binary_itration(L,a,min,max,b):
mid = (min + max)//2
if b == mid:
return -1
if L[min] == a:
return min
if L[max] == a:
return max
if L[mid] < a:
min = mid
b = mid
return binary_itration(L,a,min,max,b)
elif L[mid] > a:
max = mid
b = mid
return binary_itration(L,a,min,max,b)
elif L[mid] == a:
return mid
X=[1,2,3,4,5,6,7,8]
a=binary_itration(X,8,0,len(X)-1,-1)
print(a)
9、(10 points)《编程导论》2.5.1 节的排序算法,(A)完成选择排序和插入排序的python程序。(B)假设输入的列表是反向的,从大到小:例如N=10000;L=[i for i in range(N, 0,-1)],请分析这两种排序算法所需要的“比较”次数。哪个算法比较快?
import time;
def selectionsort(L):
start = time.clock()
for i in range(len(L)-1):
min = i
for j in range(i+1,len(L)):
if L[j] < L[min]:min = j
tempt = L[min]
L[min] = L[i]
L[i] = tempt
timeusing = time.clock() - start
printf("selection sort is ",timeusing)
return L
def insertion(L,a):
for i in range(len(L)):
if L[i]>a:
L0 = L[0:i]
L1 = L[i:len(L)]
return L0+[a]+L1
return L+[a]
def insertionsort(L):
start = time.clock()
L0=[]
for i in L:
L0 = insertion(L0,i)
timeusing = time.clock() - start
printf("insertionsort sort is ",timeusing)
return L0
L=list(range(10000,0,-1))
X=list(range(10000,0,-1))
a= selectionsort(L)
print(a)
n= insertionsort(X)
print(n)
10、(10 points)《编程导论》练习题2.5.2
L = [12,11,3,11,6,11,12,3,11]
def statistic_size(L):
L0 = []
L1 = list(set(L))
for e in L1:
count = 0
for i in L:
if e == i:
count += 1
L2 = [e,count]
L0.append(L2)
return L0
A=statistic_size(L)
print(A)
11、(10 points)《编程导论》练习题2.5.3。对于出现次数相同的元素的顺序是按照其值从小到大排序。
L = list(map(int,input().split(",")))
def statistic_sort(L,i):
a = L[i+1]
for index in range(i+1):#对L[i][1]进行比较之后再排序
if L[index][1] > a[1]:break
else:index = i+1
for k in range(i+1,index,-1):
L[k]=L[k-1]
L[index] = a
return L
def statistic_size(L):
L0 = []
L1 = list(set(L))
for e in L1:
count = 0
for i in L:
if e == i:
count += 1
L2 = [e,count]
L0.append(L2)
return L0
A=statistic_size(L)
print(A)
for i in range(len(A)-1):
A = statistic_sort(A,i)
print(A)
12、(15 points)
改写扑克牌游戏,我要你模拟不同情况下庄家的胜率。(A)按照原来的规则,庄家是等所有玩家结束后,他才开始玩牌,假设我们改变规则,庄家不是最后一个翻牌,而是先翻牌,他的胜率会降低吗?请你模拟多次比赛,最好让程序自动模拟玩家和庄家(不是手动输入),计算庄家得胜率。(B)假设庄家不是用17作为继续拿牌的标准,而是用16,18,19?其得胜率会有什么改变?这题是不是很有趣。其实这就是科研的探索。你还能想到其他什么不同的规则来测试呢?
(当年把PYTHON当成C语言写了)
def Poker():#生成牌
Number = ['A',2,3,4,5,6,7,8,9,'J','Q','K']
Type = ["♦","♣","♥","♠"]
L = []
for i in range(len(Number)):
for e in range(len(Type)):
L.append([Number[i],Type[e]])
return L
def shuffle(L):#打乱牌库
for i in range(len(L)):
j = random.randint(0,len(L)-1)
L[j],L[i] = L[i],L[j]
return L
def Player_data(Playernumber):#输入参与的人数,52张牌最多只有6个人
Players = []#有几个人参与,如闲家为1则参与人数为2
if 2 <= Playernumber:
if Playernumber <= 6:
for i in range(Playernumber):
Players.append("Player"+str(i))#初始化玩家的名字,并默认玩家1为庄家
else:
print("人数不满足要求")
return 0
return Players
def deal1(Players,Poker): #进行发牌
L = []
for i in range(len(Players)):
a = 2
X = []
X.append("Players"+str(i+1))
while a > 0:
j = random.randint(0,len(Poker)-1)
X.append(Poker[j])
#给玩家发牌
del Poker[j]#并删除掉Poker的其中一张牌
a -= 1
L.append(X)
return L,Poker
def situation_1(L):#展现一下场上的情况
A = L[0].pop()
for i in range(len(L)):
print(L[i])
L[0].append(A)
def decide(Person,Poker):#询问个人是否n进行选择
while 1:
choice = input("是否选择继续抽牌?请输入“y”或者“n”来继续游戏\n")
if choice == "y" or choice == "Y":
j = random.randint(0,len(Poker))
Person.append(Poker[j])
del Poker[j]
print(Person)
elif choice =="n" or choice == "N":
return Person,Poker
else:
print("请输入正确的指令")
def point(player):#计分
sum = 0
A = 0
for i in range(1,len(player)):
if player[i][0] == "J":
sum += 10
elif player[i][0] == "Q":
sum += 10
elif player[i][0] == "K":
sum += 10
elif player[i][0] != "A":
sum += player[i][0]
for i in range(1,len(player)):
if player[0] == "A":
A += 1
sum1 = sum
max = 0
sumA = 0
for i in range(A+1):
sumA = i + (A-i)*11
if (sumA + sum) <=21 and sumA > max:
max = sumA
sum1 = max + sum
if sum1 == sum:
sum += A
else:
return sum1
return sum
def deal2(person,Poker):#给庄家发牌
j=random.randint(0,len(Poker)-1)
person.append(Poker[j])
del Poker[j]
return person,Poker
def Judge(player2,player1,Poker,win,lose,draw):#判断闲家输赢,给庄家发牌并判断输赢
sum2 = int(point(player2))
if sum2 > 21:
print("你输了")
lose += 1
print("你的点数为%d"%sum2)
return win,lose,draw
sum1 = int(point(player1))
while sum1 < 17:
player1,Poker = deal2(player1,Poker)
sum1 = int(point(player1))
if sum1 > 21:
print("你赢了!")
win += 1
print(sum1,sum2)
return win,lose,draw
else:
if sum1 < sum2:
print("你赢了!")
win += 1
print(sum1,sum2)
return win,lose,draw
elif sum1 > sum2:
print("你输了")
lose += 1
print(sum1,sum2)
return win,lose,draw
elif sum1 == sum2:
print("平局")
draw += 1
print(sum1,sum2)
return win,lose,draw
Random_Poker = shuffle(Poker())#先进行洗牌,得到乱序的牌堆
Player = Player_data(2)#c初始化玩家数据
first_deal,Random_Poker = deal1(Player,Random_Poker)#第一次发牌,并删除发出的牌
situation_1(first_deal)#展现一下场上的情况
num1 = first_deal[0]
num2 = first_deal[1]
win = 0
lose = 0
draw = 0
num2,Random_Poker = decide(num2,Random_Poker)#选择是否继续抽牌
win,lose,draw=Judge(num2,num1,Random_Poker,win,lose,draw)#停止抽牌后判断胜负
#print(Random_Poker)
自动运行
#(自动运行版本)
import random
def Poker():#生成排好顺序的牌
Number = ['A',2,3,4,5,6,7,8,9,'J','Q','K']
Type = ["♦","♣","♥","♠"]
L = []
for i in range(len(Number)):
for e in range(len(Type)):
L.append([Number[i],Type[e]])
return L
def shuffle(L):#打乱牌库
for i in range(len(L)):
j = random.randint(0,len(L)-1)
L[j],L[i] = L[i],L[j]
return L
def Player_data(Playernumber):#输入参与的人数,52张牌最多只有6个人
Players = []#有几个人参与,如闲家为1则参与人数为2
if 2 <= Playernumber:
if Playernumber <= 6:
for i in range(Playernumber):
Players.append("Player"+str(i))#初始化玩家的名字,并默认玩家1为庄家
else:
print("人数不满足要求")
return 0
return Players
def deal1(Players,Poker): #进行发牌
L = []
for i in range(len(Players)):
a = 2
X = [] #生成一个列表,里面装着i个列表元素
X.append("Players"+str(i+1))#每一个列表元素里面第一个内容是字符串“Player(i)
while a > 0: #每个玩家发两张牌
j = random.randint(0,len(Poker)-1)
X.append(Poker[j])
del Poker[j]#并删除掉Poker的其中一张牌
a -= 1
L.append(X)
return L,Poker#返回玩家和所获得牌,并删除四张已经发下来的牌
def point(player):#计分
sum = 0
A = 0
for i in range(1,len(player)):
if player[i][0] == "J":
sum += 10
elif player[i][0] == "Q":
sum += 10
elif player[i][0] == "K":
sum += 10
elif player[i][0] != "A":
sum += player[i][0]
for i in range(1,len(player)):
if player[0] == "A":
A += 1
sum1 = sum
max = 0
sumA = 0
for i in range(A+1):
sumA = i + (A-i)*11
if (sumA + sum) <=21 and sumA > max:
max = sumA
sum1 = max + sum
if sum1 == sum:#如果发现上一个for循环没加上数,说明A全取1的数值都会导致数据大于21点,所以下方直接让sum加上i个1
sum += A
else:
return sum1
return sum
def auto(Person,Poker):#让程序自动决定是否抽牌,输入的数值为闲家的数据,并输入剩余的48张牌
judge_number = int(point(Person))
while 1:
a = random.random()#生成抽牌的概率
if judge_number <= 11:#数据小于等于11则选择抽
j = random.randint(0,len(Poker)-1)
Person.append(Poker[j])
del Poker[j]
judge_number = point(Person)
elif 11 < judge_number <= 21:#每当数据大于11一个单位,则抽的概率减少10%.
if a > 0.1*(judge_number - 11):
j = random.randint(0,len(Poker)-1)
Person.append(Poker[j])
del Poker[j]
judge_number = point(Person)
else:return Person,Poker
else:
return Person,Poker
def deal2(person,Poker):#给庄家发牌
j=random.randint(0,len(Poker)-1)
person.append(Poker[j])
del Poker[j]
return person,Poker
def Judge(player2,player1,Poker,win,lose,draw):#判断闲家输赢,给庄家发牌并判断输赢
sum2 = int(point(player2))
if sum2 > 21:
print("你输了")
lose += 1
print(player1)
print(player2)
print("你的点数为%d"%sum2)
return win,lose,draw
sum1 = int(point(player1))
while sum1 < 17:
player1,Poker = deal2(player1,Poker)
sum1 = int(point(player1))
if sum1 > 21:
print("你赢了!")
win += 1
print(player1)
print(player2)
print(sum1,sum2)
return win,lose,draw
else:
if sum1 < sum2:
print("你赢了!")
win += 1
print(player1)
print(player2)
print(sum1,sum2)
return win,lose,draw
elif sum1 > sum2:
print("你输了")
lose += 1
print(player1)
print(player2)
print(sum1,sum2)
return win,lose,draw
elif sum1 == sum2:
print("平局")
print(player1)
print(player2)
draw += 1
print(sum1,sum2)
return win,lose,draw
def matching():
win=0
lose=0
draw=0
Random_Poker = shuffle(Poker())#先进行洗牌,得到乱序的牌堆
Player = Player_data(2)#c初始化玩家数据
first_deal,Random_Poker = deal1(Player,Random_Poker)#第一次发牌,并删除发出的牌
num1 = first_deal[0]
num2 = first_deal[1]
num2,Random_Poker = auto(num2,Random_Poker)#程序选择抽牌
win,lose,draw=Judge(num2,num1,Random_Poker,win,lose,draw)#停止抽牌后判断胜负,并记录输赢和的次数
#由于只需要计算庄家胜利的概率,故返回lose的次数即可。
return lose
def main():
times = int(input("输入模拟次数:"))
sUm = 0
for i in range(times):
sUm += matching()
print("--------------模拟完成--------------")
print("庄家获胜概率为:",sUm/times)
if __name__ == "__main__":
main()