python 程序设计代码 5-8章

第五章

例5.1.1 逆序数的逆序和

输入两个正整数,先将它们分别倒过来,然后再相加,最后再将结果倒过来输出。注意:前置的零将被忽略。例如,输入305和794。倒过来相加得到1000,输出时只要输出1就可以了。测试数据保证结果在int类型的表示范围内。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入两个正整数a、b。

输出格式:
对于每组测试,将a、b逆序后求和并逆序输出(前导0不需输出)。

输入样例:
2
21 6
123 456
输出样例:
81
579

点击查看代码
def rev(a):
    r=0
    while a>0:
        r=r*10+a%10
        a=a//10
    return r
T=int(input())
for i in range(T):
    a,b=map(int,input().split())
    res=rev(rev(a)+rev(b))
    print(res)

例5.4.3 斐波那契数列

“兔子问题”假定一对大兔子每一个月可以生一对小兔子,而小兔子出生后两个月就有繁殖能力,问从一对小兔子开始,n个月后能繁殖成多少对兔子?

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入一个正整数n(1≤n≤46)。

输出格式:
对于每组测试,输出n个月后能繁殖成的兔子对数。

输入样例:
1
4
输出样例:
3

点击查看代码
N=1000
f=[0]*(N+1)
def init():
    f[1]=f[2]=1
    for i in range(3,N+1):
        f[i]=f[i-1]+f[i-2]

init()
T=int(input())
for i in range(T):
    n=int(input())
    print(f[n])

      

例5.4.4 快速幂a^b

输入两个整数a、b,求a^b。结果保证在long long int范围内。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入两个正整数a,b(1≤a,b≤62)。

输出格式:
对于每组测试,输出a b的结果。

输入样例:
2 4
输出样例:
16

点击查看代码
def a_b(a,b):
    if b==0:
        return 1
    else:
        t=a_b(a,b//2)
        if b%2==0:
            return t*t
        elif b%2==1:
            return t*t*a

try:
    while True:
       a,b=map(int,input().split())
       print(a_b(a,b))
except EOFError:pass

例5.5.1 验证哥德巴赫猜想

哥德巴赫猜想之一是指一个偶数(2除外)可以拆分为两个素数之和。请验证这个猜想。
因为同一个偶数可能可以拆分为不同的素数对之和,这里要求结果素数对彼此最接近。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入1个偶数n(6≤n≤10000)。

输出格式:
对于每组测试,输出两个彼此最接近的素数a、b(a≤b),两个素数之间留1个空格。

输入样例:
2
30
40
输出样例:
13 17
17 23

点击查看代码
from math import sqrt
def isPrime(x):
    if x<=2:
        return False
    for i in range(2,int(sqrt(n))+1):
        if x%i==0:
            return False
            break
    else:
        return True
            
T=int(input())
for i in range(T):
    n=int(input())
    if n%2==0:
        for j in range(n//2,1,-1):
             if isPrime(j)==True and isPrime(n-j)==True:
                print(j,n-j)
                break


例5.5.2 素数排位

已知素数序列为2、3、5、7、11、13、17、19、23、29……,即素数的第一个是2,第二个是3,第三个是5……那么,随便挑一个数,若是素数,能确定是第几个素数吗?如果不是素数,则输出0。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一正整数N(1≤N≤1000000)。

输出格式:
对于每组测试,输出占一行,如果输入的正整数是素数,则输出其排位,否则输出0。

输入样例:
2
6
4
5
13
输出样例:
1
0
0
3
6

点击查看代码
N=1000000
index=[1]*(N+1)
def init():
    index[0]=index[1]=0
    cnt=1
    for i in range(2,N+1):
        if index[i]==0:
            continue
        index[i]=cnt
        cnt+=1
        for j in range(i*i,N+1,i):
            index[j]=0
init()
try:
    while True:
       n=int(input())
       print(index[n])
except EOFError:pass



例5.5.3 母牛问题

设想一头小母牛从第4个年头开始每年生育一头小母牛。现有一头小母牛,按照此设想,第n年时有多少头母牛?

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个正整数n(1≤n≤40)。

输出格式:
对于每组测试,输出第n年时的母牛总数。

输入样例:
5
8
15
输出样例:
3
9
129

点击查看代码
def f(n):
    if n<4:
        return 1
    else:
        return f(n-1)+f(n-3)
try:
    while True:
       n=int(input())
       print(f(n))
except EOFError:pass

例5.5.4 特殊排序

输入一个整数n和n个各不相等的整数,将这些整数从小到大进行排序,要求奇数在前,偶数在后。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试先输入一个整数n(1<n<100),再输入n个整数。

输出格式:
对于每组测试,在一行上输出根据要求排序后的结果,数据之间留一个空格。

输入样例:
3
5 1 2 3 4 5
3 12 4 5
6 2 4 6 8 0 1
输出样例:
1 3 5 2 4
5 4 12
1 0 2 4 6 8

点击查看代码
def j_o_sort(n,a):
    k=0
    for i in range(n):
        if a[i]%2==1:
            if k>0:
               print(" ",end="")
            print(a[i],end="")
            k+=1
            
    s=0
    for i in range(n):
        if a[i]%2==0:
            if s>=0:
               print(" ",end="")
            print(a[i],end="")
            s+=1
            
T=int(input())
for t in range(T):
    a=list(map(int,input().split()))
    n=a[0]
    a=a[1:]
    a.sort()
    j_o_sort(n,a)
    print()
    #print(a)

例5.5.5 平方和排序

输入int类型范围内的N个非负整数,要求按各个整数的各数位上数字的平方和从小到大排序,若平方和相等则按数值从小到大排序。
例如,三个整数9、31、13各数位上数字的平方和分别为81、10、10,则排序结果为13、31、9。

输入格式:
测试数据有多组。每组数据先输入一个整数N(0<N<100),然后输入N个非负整数。若N=0,则表示输入结束。

输出格式:
对于每组测试,在一行上输出按要求排序后的结果,数据之间留一个空格。

输入样例:
9
12 567 91 33 657 812 2221 3 77
5
1 3 11 33 9
0
输出样例:
12 3 2221 33 812 91 77 567 657
1 11 3 33 9

点击查看代码
from functools import cmp_to_key
def cmp(a,b):
    sa=squreSum(a)
    sb=squreSum(b)
    if sa!=sb:
        return sa-sb    #平方和不等,按平方和从小到大
    return a-b          #平方和相等,按数值本身从小到大
def squreSum(n):
    sum=0
    while n>0:
        sum+=(n%10)**2
        n=n//10    #整除
    return sum
while True:
    n=int(input())
    if n==0: break
    a=list(map(int,input().split()))
    a.sort(key=cmp_to_key(cmp)) #调用原有函数cmp_to_key获得key
    print(*a)

例5.5.7 按日期排序

输入若干日期,按日期从小到大排序。

输入格式:
本题只有一组测试数据,且日期总数不超过100个。按“MM/DD/YYYY”的格式逐行输入若干日期。

输出格式:
按“MM/DD/YYYY”的格式输出已从小到大排序的各个日期,每个日期占一行。

输入样例:
12/31/2005
10/21/2003
02/12/2004
11/12/1999
10/22/2003
11/30/2005
输出样例:
11/12/1999
10/21/2003
10/22/2003
02/12/2004
11/30/2005
12/31/2005

点击查看代码
from functools import cmp_to_key
def cmp(a,b):
    a=a[6:]+a[:2]+a[3:5]
    b=b[6:]+b[:2]+b[3:5]
    if a<b:
        return -1
    else:
        return 1
def output(a):
    for i in range(len(a)):
        print(a[i])
a=[]
try:
    while True:
        t=input()
        a.append(t)
except EOFError:pass
a.sort(key=cmp_to_key(cmp))
output(a)

习题5.2.2, HLOJ 2054 整数转换为字符串

将一个整数n转换成字符串。例如;输入483,应得到字符串"483"。其中,要求用一个递归函数实现把一个正整数转换为字符串。

输入格式:
首先输入测试组数T,然后输入T组测试数据。每组测试数据输入一个整数n(-231≤n≤231-1)。

输出格式:
对于每组测试,输出转换后的字符串。

输入样例:
1
1234
输出样例:
1234

点击查看代码
T=int(input())
for i in range(T):
    n=input()
    n=str(n)
    print(n)

习题5.2.3 多个数的最小公倍数

两个整数公有的倍数称为它们的公倍数,其中最小的一个正整数称为它们两个的最小公倍数。当然,n个数也可以有最小公倍数,例如:5,7,15的最小公倍数是105。
输入n个数,请计算它们的最小公倍数。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试先输入一个整数n(2≤n≤20),再输入n个正整数(属于[1,100000]范围内)。这里保证最终的结果在int型范围内。

输出格式:
对于每组测试,输出n个整数的最小公倍数。

输入样例:
3
3 5 7 15
5 1 2 4 3 5
8 7 15 12 3 4 6 4 9
输出样例:
105
60
1260

点击查看代码
def gcd(m,n):    #最大公约数
    if m%n==0:
        return n
    else:
        return gcd(n,m%n)

def lcm(m,n):    #最小公倍数
    return m//gcd(m,n)*n

T=int(input())
for t in range(T):
    a=list(map(int,input().split()))
    n=a[0]
    a=a[1:]
    res=1
    for i in range(n):
        res=lcm(res,a[i])
    print(res)

习题5.2.4 互质数

Sg认识到互质数很有用。若两个正整数的最大公约数为1,则它们是互质数。要求编写函数判断两个整数是否互质数。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试先输入1个整数n(1≤n≤100),再输入n行,每行有一对整数a、b(0<a,b<10^9)。

输出格式:
对于每组测试数据,输出有多少对互质数。

输入样例:
1
3
3 11
5 11
10 12
输出样例:
2

点击查看代码
def gys(m,n):
    if m%n==0:
        return n
    else:
        return gys(n,m%n)
def hz(m,n):
    return gys(m,n)==1

T=int(input())
for i in range(T):
    n=int(input())
    num=0
    for j in range(n):
        a,b=map(int,input().split())
        if hz(a,b):
            num+=1
    print(num)

习题5.2.5 五位以内的对称素数

判断一个数是否为对称且不大于五位数的素数。要求判断对称和判断素数各写一个函数。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个正整数n(0 < n < 232)。

输出格式:
对于每组测试,若n是不大于五位数的对称素数,则输出“Yes”,否则输出“No”。每个判断结果单独占一行。注意:引号不必输出。

输入样例:
11
101
272
33533
2147483647
输出样例:
Yes
Yes
No
Yes
No

点击查看代码
from math import sqrt
def dc_5(a):
    b=str(a)
    if len(b)>5:
        return False
    for i in range(len(b)//2):
        if b[i]!=b[len(b)-i-1]:
            return False
            break
    return True
        
def sushu(a):
    if a<2:
        return False
    for i in range(2,int(sqrt(a))//2+1):#不能忘记少加+1
        if a%i==0:
            return False
        break
    return True
    
try:
    while True:
       n=int(input())
       if sushu(n) and dc_5(n):
            print('Yes')
       else:
            print('No')
except EOFError:pass


习题5.2.6 最长的单词

输入一个字符串,将此字符串中最长的单词输出。要求至少使用一个自定义函数。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据输入一个字符串(长度不超过80)。

输出格式:
对于每组测试,输出字符串中的最长单词,若有多个长度相等的最长单词,输出最早出现的那个。这里规定,单词只能由大小写英文字母构成。

输入样例:
Keywords insert, two way insertion sort,
Abstract This paper discusses three method for two way insertion
words. insert, two way sorted.
输出样例:
insertion
discusses
insert

点击查看代码
def check(a):
    return (a>='a'and a<='z') or (a>='A' and a<='Z')

try:
    while True:
        a=input()
        for i in range(len(a)): #将非字母的字符转换为空格
            if check(a[i])==False:
                a=a.replace(a[i],' ')#方法replace()不会改变原有串
        a=a.split()  #根据空格分割得到单词列表
        res=""
        for i in range(len(a)):
            if len(res)<len(a[i]):
                res=a[i]
        print(res)
except EOFError:pass        

习题5.2.8 旋转方阵

对于一个奇数n阶方阵,请给出经过顺时针方向m次旋转后的结果。

输入格式:
测试数据有多组,处理到文件尾。每组测试的第一行输入2个整数n,m(1<n<20,1≤m≤100),接下来输入n行数据,每行n个整数。

输出格式:
对于每组测试,输出奇数阶方阵经过m次顺时针方向旋转后的结果。每行中各数据之间留一个空格。

输入样例:
3 2
4 9 2
3 5 7
8 1 6
3 1
4 9 2
3 5 7
8 1 6
3 7
4 9 2
3 5 7
8 1 6
3 8
4 9 2
3 5 7
8 1 6
输出样例:
6 1 8
7 5 3
2 9 4
8 3 4
1 5 9
6 7 2
2 7 6
9 5 1
4 3 8
4 9 2
3 5 7
8 1 6

点击查看代码
def x_z(a):
    n=len(a)
    for i in range(n):
        for j in range(i):
            a[i][j],a[j][i]=a[j][i],a[i][j]
    for j in range(n//2):
        for i in range(n):
            a[i][j],a[i][n-j-1]=a[i][n-j-1],a[i][j]
    
try:
    while True:
        n,m=map(int,input().split())
        a=[]
        for i in range(n):
            t=list(map(int,input().split()))
            a.append(t)
        m=m%4
        for i in range(m):
            x_z(a)
        for i in range(n):
            print(*a[i])
except EOFError:pass

习题5.2.9 求矩阵中的逆鞍点

求出n×m二维整数数组中的所有逆鞍点。这里的逆鞍点是指在其所在的行上最大,在其所在的列上最小的元素。若存在逆鞍点,则输出所有逆鞍点的值及其对应的行、列下标。若不存在逆鞍点,则输出“Not”。要求至少使用一个自定义函数。

输入格式:
测试数据有多组,处理到文件尾。每组测试的第一行输入n和m(都不大于100),第二行开始的n行每行输入m个整数。

输出格式:
对于每组测试,若存在逆鞍点,则按行号从小到大、同一行内按列号从小到大的顺序逐行输出每个逆鞍点的值和对应的行、列下标,每两个数据之间一个空格;若不存在逆鞍点,则在一行上输出“Not”(引号不必输出)。

输入样例:
3 3
97 66 96
85 36 85
88 67 91
3 4
73 89 74 76
6 33 74 0
27 57 6 32
输出样例:
85 1 0
85 1 2
Not

点击查看代码
def check(a,r,c):
    for j in range(len(a[r])):  #非行上最大
        if a[r][j]>a[r][c]:
            return False
    for i in range(len(a)):     #非列上最小
        if a[i][c]<a[r][c]:
            return False
    return True

try:
    while True:
        n,m=map(int,input().split())
        a=[]
        for i in range(n): 
            t=list(map(int,input().split()))
            a.append(t)
        
        cnt=0
        for i in range(n):
            for j in range(m):
                if check(a,i,j)==True:
                    cnt+=1
                    print(a[i][j],i,j)
  
        if cnt==0:
            print("Not")
except EOFError:pass 

第六章

例6.1.1 进步排行榜

假设每个学生信息包括“用户名”、“进步总数”和“解题总数”。解题进步排行榜中,按“进步总数”及“解题总数”生成排行榜。要求先输入n个学生的信息;然后按“进步总数”降序排列;若“进步总数”相同,则按“解题总数”降序排列;若“进步总数”和“解题总数”都相同,则排名相同,但输出信息时按“用户名”升序排列。

输入格式:
首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据先输入一个正整数n(1 < n < 50),表示学生总数。然后输入n行,每行包括一个不含空格的字符串s(不超过8位)和2个正整数d和t,分别表示用户名、进步总数和解题总数。

输出格式:
对于每组测试,输出最终排名。每行一个学生的信息,分别是排名、用户名、进步总数和解题总数。每行的各个数据之间留一个空格。注意,进步总数和解题总数都相同的学生其排名也相同。

输入样例:
2
6
usx15131 21 124
usx15101 27 191
usx15113 31 124
usx15136 18 199
usx15117 27 251
usx15118 21 124
10
usx15131 21 124
usx15101 27 191
usx15107 24 154
usx15113 31 124
usx15117 25 251
usx15118 21 124
usx15119 22 117
usx15121 43 214
usx15128 21 124
usx15136 28 199
输出样例:
1 usx15113 31 124
2 usx15117 27 251
3 usx15101 27 191
4 usx15118 21 124
4 usx15131 21 124
6 usx15136 18 199
1 usx15121 43 214
2 usx15113 31 124
3 usx15136 28 199
4 usx15101 27 191
5 usx15117 25 251
6 usx15107 24 154
7 usx15119 22 117
8 usx15118 21 124
8 usx15128 21 124
8 usx15131 21 124

点击查看代码
from functools import cmp_to_key
class S:
    def __init__(self,name,upcount,count):
        self.name=name
        self.upcount=upcount
        self.count=count

def cmp(a,b):
    up_a=a.upcount
    up_b=b.upcount
    co_a=a.count
    co_b=b.count
    if up_a!=up_b:
        return up_b-up_a
    elif co_a!=co_b:
        return co_b-co_a
    if a.name<b.name:
        return -1
    else:
        return 1

T=int(input())
for i in range(T):
    n=int(input())
    a=[]
    for i in range(n):
        t=input().split()
        a.append(S(t[0],int(t[1]),int(t[2])))
    a.sort(key=cmp_to_key(cmp))
    r=1
    print(r,a[0].name,a[0].upcount,a[0].count)
    for i in range(1,n):
        if a[i].upcount!=a[i-1].upcount or a[i].count!=a[i-1].count:
            r=i+1
        print(r,a[i].name,a[i].upcount,a[i].count)

例6.3.1 平均成绩

输入n个学生的姓名及其3门功课成绩,要求按输入的逆序逐行输出每个学生的姓名、3门课成绩和平均成绩。若有学生平均成绩低于60分,则不输出该学生信息。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入一个正整数n(1<n<100),表示学生人数;然后是n行信息,分别表示学生的姓名(长度不超过10且由英文字母构成的字符串)和3门课成绩(正整数)。

输出格式:
对于每组测试,输出所有满足要求的学生信息,每行一个学生信息:姓名、3门课成绩和平均成绩(保留2位小数)。每行的每两个数据之间留一个空格。

输入样例:
3
zhangsan 80 75 65
lisi 65 52 56
wangwu 87 86 95
6
zhangsan 80 75 65
qisi 78 77 56
wangwu 87 86 95
zisi 78 77 56
wangwu 88 86 95
lisi 65 52 56
输出样例:
wangwu 87 86 95 89.33
zhangsan 80 75 65 73.33
wangwu 88 86 95 89.67
zisi 78 77 56 70.33
wangwu 87 86 95 89.33
qisi 78 77 56 70.33
zhangsan 80 75 65 73.33

点击查看代码
class S:
    def __init__(self,name,s1,s2,s3):
        self.name=name
        self.s1=s1
        self.s2=s2
        self.s3=s3
        self.avg=(s1+s2+s3)/3

try:
    while True:
        n=int(input())
        a=[]
        for i in range(n):
            t=input().split()
            a.append(S(t[0],int(t[1]),int(t[2]),int(t[3])))
        
        for i in range(n-1,-1,-1):
            if a[i].avg<60:
                continue
            print(a[i].name,a[i].s1,a[i].s2,a[i].s3,end=" ")
            print("%.2f"%a[i].avg)
except EOFError:pass

例6.3.2 成绩排序

输入n个学生的姓名及其3门功课成绩(整数),要求根据3门功课的平均成绩从高分到低分输出每个学生的姓名、3门功课成绩及平均成绩,若平均分相同则按姓名的字典序输出。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入一个正整数n(1<n<100),表示学生人数;然后是n行信息,分别表示学生的姓名(长度不超过10且由英文字母构成的字符串)和3门课成绩(正整数)。

输出格式:
对于每组测试,输出排序后的学生信息,每行一个学生信息:姓名、3门课成绩、平均成绩(保留2位小数)。每行数据之间留一个空格。

输入样例:
3
zhangsan 80 75 65
lisi 65 52 56
wangwu 87 86 95
输出样例:
wangwu 87 86 95 89.33
zhangsan 80 75 65 73.33
lisi 65 52 56 57.67

点击查看代码
from functools import cmp_to_key
class S:
    def __init__(self,name,s1,s2,s3):
        self.name=name
        self.s1=s1
        self.s2=s2
        self.s3=s3
        self.avg=(s1+s2+s3)/3
def cmp(a,b):
    if a.avg!=b.avg:
        return b.avg-a.avg
    if a.name<b.name:
        return -1
    else:
        return 1
try:
    while True:
        n=int(input())
        a=[]
        for i in range(n):
            t=input().split()
            a.append(S(t[0],int(t[1]),int(t[2]),int(t[3])))
        
        a.sort(key=cmp_to_key(cmp))

        for i in range(n):
            print(a[i].name,a[i].s1,a[i].s2,a[i].s3,end=" ")
            print("%.2f"%a[i].avg)
except EOFError:pass

例6.4.1 小霸王

有个小朋友(小霸王)觉得自己的橡皮泥少了,就从另一个小朋友那里抢了一些。请问,是哪个小霸王抢了哪个小朋友的橡皮泥?
输入格式:
测试数据有多组。对于每组测试,首先输入一个整数n(n≤500),然后输入n行,每行包括3个不超过1000的整数l、w、h和1个字符串name(不超过8个字符且不含空格),其中,l、w、h分别表示橡皮泥的长、宽、高,name表示小朋友的姓名。当n等于-1时,输入结束。

输出格式:
对于每组测试,按“name1 took clay from name2.”的格式输出一行,其中name1代表小霸王的名字,name2代表被抢小朋友的名字,具体参考输出样例。

输入样例:
3
10 10 2 Jill
5 3 10 Will
5 5 10 Bill
-1
输出样例:
Bill took clay from Will.

点击查看代码
class S:
    def __init__(self,l,w,h,name):
        self.volume=l*w*h
        self.name=name
while True:
    n=int(input())
    a=[]
    if n==-1:
        break
    for i in range(n):
        t=input().split()
        a.append(S(int(t[0]),int(t[1]),int(t[2]),t[3]))
    j=0
    k=0
    for i in range(n):
        if a[i].volume<a[j].volume:
            j=i
        if a[i].volume>=a[k].volume:
            k=i
    print("%s took clay from %s." %(a[k].name,a[j].name))

例6.4.4 获奖

在某次竞赛中,判题规则是按解题数从多到少排序,在解题数相同的情况下,按总成绩(保证各不相同)从高到低排序,取排名前60%的参赛队(四舍五入取整)获奖,请确定某个队能否获奖。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试的第一行输入1个整数n(1≤n≤15)和1个字符串ms(长度小于10且不含空格),分别表示参赛队伍总数和想确定是否能获奖的某个队名;接下来的n行输入n个队的解题信息,每行一个1个字符串s(长度小于10且不含空格)和2个整数m,g(0≤m≤10,0≤g≤100),分别表示一个队的队名、解题数、成绩。当然,n个队名中肯定包含ms。

输出格式:
对于每组测试,若某队能获奖,则输出“YES”,否则输出“NO”。引号不必输出。

输入样例:
1
3 team001
team001 2 27
team002 2 28
team003 0 7
输出样例:
YES

点击查看代码
from functools import cmp_to_key
class Team:
    def __init__(self,name,diff,score):
        self.name=name
        self.diff=diff
        self.score=score
        
def cmp(a,b):
    if a.diff!=b.diff:
        return b.diff-a.diff
    else:
        return b.score-a.score
T=int(input())
for i in range(T):
    b=input().split()
    n=int(b[0])
    nm=b[1]
    a=[]
    for i in range(n):
        name,diff,score=input().split()
        a.append(Team(name,int(diff),int(score)))
    
    a.sort(key=cmp_to_key(cmp))
#     for i in range(n):
#        print(a[i].name,a[i].diff,a[i].score)
    
    xiaoshu=n*0.6-int(n*0.6) #四舍五入的小数
    if xiaoshu>=0.5:
        m=int(n*0.6)+1
    else:
        m=int(n*0.6)
   
    flag=True
    for i in range(m):
        if nm==a[i].name:
            print("YES")
            break
    else:
        print("NO")
   
    

例6.4.5 竞赛排名

某循环赛的比赛规则是胜者得3分,和者得1分,败者不得分。请根据各人总得分从高到低进行排名。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试先输入一个整数n(2≤n≤100),表示参赛人数,然后输入n*(n-1)/2行,每行一个比赛结果。每行比赛结果由A、B、f构成,A和B为参赛人名(不含空格),f=1表示A胜B,f=0表示A与B打和。由于总是将胜者排在前面,所以不存在A败于B的情况。

输出格式:
对于每组测试,按名次分行输出,名次与名字之间以一个空格间隔,并列名次的名字在同一行输出,按字典序以一个空格隔开。

输入样例:
2
3
Jack Smith 0
Smith Bob 1
Jack Bob 1
6
a b 1
c a 0
a d 0
a e 1
f a 1
b c 1
d b 0
e b 0
f b 0
c d 1
c e 1
c f 1
d e 0
f d 0
e f 0
输出样例:
1 Jack Smith
3 Bob
1 c
2 a
3 b f
5 d
6 e

点击查看代码
class Player:                           #类定义
    def __init__(s,name):
        s.name=name                     #数据成员姓名name
        s.score=0                       #数据成员成绩score

def cmp(x,y):                           #比较函数
    if x.score!=y.score:                #若成绩不等,则按成绩逆序
        return y.score-x.score
    if x.name<y.name:                   #若成绩相等,则按姓名正序
        return -1
    else:
        return 1

#查找函数,在对象列表a中查找数据成员name等于参数sname的元素,返回其下标,若找不到则返回-1
def find(a,sname):
    n=len(a)
    for i in range(n):
        if a[i].name==sname:
            return i
    return -1
from functools import cmp_to_key
T=int(input())
for t in range(T):
    n=int(input())
    m=n*(n-1)//2    #记录 取整
    a=[]
    for i in range(m):
        name1,name2,flag=input().split()
        k1=find(a,name1)
        if k1>=0:
            k=k1
        else:
            k=len(a)
            a.append(Player(name1))
        
        if flag=="0":
            a[k].score+=1
        else:
            a[k].score+=3
         
        k2=find(a,name2)
        if k2>=0:
            k=k2
        else:
            k=len(a)
            a.append(Player(name2))
            
        if flag=="0":
            a[k].score+=1
    
    a.sort(key=cmp_to_key(cmp))
    r=1
    print(r,a[0].name,end='')
    for i in range(1,n):
        if a[i].score==a[i-1].score:
            print('',a[i].name,end='')
        else:
            print()
            r=i+1
            print(r,a[i].name,end='')
    print()

习题6.2.1 倒置排序

将一些整数按倒置值从小到大排序后输出。倒置是指把整数的各个数位倒过来构成一个新数,例如:13倒置成了31。若倒置值相同则按原数的从小到大排序,例如130和13,倒置数都是31,则13排在130前面。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试先输入一个整数n(n≤80),然后输入n个非负整数。

输出格式:
对于每组测试,结果占一行,输出排序后的结果,数据之间留一个空格。

输入样例:
2
4 83 13 24 36
4 99 100 123 12345
输出样例:
13 83 24 36
100 99 123 12345

点击查看代码
from functools import cmp_to_key
def reverse(a):
    s=0
    while a>0:   #记得加限制条件
        s=s*10+a%10
        a=a//10
    return s

def cmp(a,b):
    ar=reverse(a)
    br=reverse(b)
    if ar!=br:
        return ar-br
    if a<b:
        return -1
    else:
        return 1
    
T=int(input())
for t in range(T):
    a=list(map(int,input().split()))
    n=a[0]
    a=a[1:]
    a.sort(key=cmp_to_key(cmp))
    print(*a)
    

习题6.2.3 足球联赛排名

本赛季足球联赛结束了。请根据比赛结果,给队伍排名。排名规则:
(1)先看积分,积分高的名次在前(每场比赛胜者得3分,负者得0分,平局各得1分);
(2)若积分相同,则看净胜球(该队伍的进球总数与失球总数之差),净胜球多的排名在前;
(3)若积分和净胜球都相同,则看总进球数,进球总数多的排名在前;
(4)若积分、净胜球和总进球数都相同,则队伍编号小的排名在前。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试先输入一个正整数n(n<1000),代表参赛队伍总数。方便起见,队伍以编号1,2,……,n表示。然后输入n*(n-1)/2行数据,依次代表包含这n个队伍之间进行单循环比赛的结果,具体格式为:i j p q, 其中i、j分别代表两支队伍的编号(1≤i<j≤n),p、q代表队伍i和队伍j的各自进球数(0≤p,q≤50)。

输出格式:
对于每组测试数据,按比赛排名从小到大依次输出队伍的编号,每两个队伍之间留一个空格。

输入样例:
2
4
1 2 0 2
1 3 1 1
1 4 0 0
2 3 2 0
2 4 4 0
3 4 2 2
3
1 2 3 0
1 3 1 1
2 3 0 0
输出样例:
2 3 1 4
1 3 2

点击查看代码
class Team:
    def __init__(s,index,score,win_ball,sum_ball):
        s.index=index
        s.score=score
        s.win_ball=win_ball
        s.sum_ball=sum_ball
def cmp(a,b):
    if a.score!=b.score:
        return b.score-a.score
    if a.win_ball!=b.win_ball:
        return b.win_ball-a.win_ball
    if a.sum_ball!=b.sum_ball:
        return b.sum_ball-a.sum_ball
    if a.index<b.index:
        return -1
    else:
        return 1


from functools import cmp_to_key
T=int(input())
for t in range(T):
    n=int(input())
    m=n*(n-1)//2
    a=[Team(n+1,0,0,0)]
    for i in range(n):
        a.append(Team(i+1,0,0,0))
    for i in range(m):
        id1,id2,win1,win2=map(int,input().split())
        a[id1].win_ball+=win1-win2
        a[id1].sum_ball+=win1
        a[id2].win_ball+=win2-win1       
        a[id2].sum_ball+=win2
        if win1==win2:
            a[id1].score+=1
            a[id2].score+=1
        elif win1>win2:
            a[id1].score+=3
        else:
            a[id2].score+=3
    a.sort(key=cmp_to_key(cmp))
    for i in range(n):
        if i>0:
            print(' ',end='')
        print(a[i].index,end='')
    print()
        
        

第七章

例7.3.1 顺序建立链表

输入一个整数n,再输入n个整数,按照输入的顺序建立单链表,并遍历所建立的单链表,输出这些数据。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n,再输入n个整数。

输出格式:
对于每组测试,输出顺序链表中的各结点的数据域的值(数据之间留一个空格)。

输入样例:
5 1 2 3 4 5
输出样例:
1 2 3 4 5

点击查看代码
class Node:
    def __init__(self,data):
        self.data=data
        self.next=None

#尾插法
def createByTail(a):
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

#遍历
def output(head):
    p=head.next
    while p!=None:
        if p!=head.next:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()
try:
    while True:
        a=list(map(int,input().split()))
        n=a[0]
        a=a[1:]
        h=createByTail(a)
        output(h)
except EOFError:pass

例7.3.2 逆序建立链表

输入一个整数n,再输入n个整数,按照输入的顺序建立单链表,并遍历所建立的单链表,输出这些数据。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n,再输入n个整数。

输出格式:
对于每组测试,输出顺序链表中的各结点的数据域的值(数据之间留一个空格)。

输入样例:
5 1 2 3 4 5
输出样例:
5 4 3 2 1

点击查看代码
class Node:
    def __init__(self,data):
        self.data=data
        self.next=None

def createByFront(a):
    head=Node(-1)
    for i in range(len(a)):
        p=Node(a[i])
        p.next=head.next
        head.next=p
    return head

def output(head):
    p=head.next
    while p!=None:
        if p!=head.next:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()

try:
    while True:
        a=list(map(int,input().split()))
        n=a[0]
        a=a[1:]
        h=createByFront(a)
        output(h)
except EOFError:pass

例7.4.1 单链表就地逆置

输入多个整数,以-1作为结束标志,顺序建立一个带头结点的单链表,之后对该单链表进行就地逆置(不增加新结点),并输出逆置后的单链表数据。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入多个整数,以-1作为该组测试的结束(-1不处理)。

输出格式:
对于每组测试,输出逆置后的单链表数据(数据之间留一个空格)。

输入样例:
1
1 2 3 4 5 -1
输出样例:
5 4 3 2 1

点击查看代码
class Node:                 #定义类
    def __init__(self, data):
        self.data=data
        self.next=None

def createByTail(a):        #创建顺序链表
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

#逆置链表,每次取下原链表的第一个数据结点链接到新链表的头结点之后,第一个数据结点之前
def reverse(head):          #head为头结点
    p=head.next             #p“指向”第一个数据结点
    head.next=None          #头结点指针域置为空值
    while p!=None:          #当链表还没有扫描结束
        q=p                 #q“指向”结点p(原链表的第一个数据结点)
        p=p.next            #p“指向”下一个结点
        q.next=head.next    #结点q链接到第一个数据结点(第一次为None)之前
        head.next=q         #结点q链接到头结点之后

def output(head):           #遍历链表
    p=head.next
    while p!=None:
        if p!=head.next:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()

T=int(input())
for t in range(T):
    a=list(map(int,input().split()))
    a=a[:len(a)-1]          #把-1去掉
    h=createByTail(a)
    reverse(h)
    output(h)

例7.4.3 保持链表有序

对于输入的若干学生的信息,按学号顺序从小到大建立有序链表,最后遍历链表,并按顺序输出学生信息。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(1≤n≤100),表示学生的个数。然后输入n行信息,分别是学生的学号和姓名,其中,学号是8位的正整数(保证各不相同),姓名是长度不超过10且不含空格的字符串。

输出格式:
对于每组测试,按顺序输出学生信息,学号和姓名之间留一个空格(参看输出样例)。

输入样例:
1
3
20080108 Zhangsan
20070328 Lisi
20070333 Wangwu
输出样例:
20070328 Lisi
20070333 Wangwu
20080108 Zhangsan

点击查看代码
class Node:
    def __init__(self,sno=0,sname=""):
        self.sno=sno
        self.sname=sname
        self.next=None

def output(head):                   #遍历链表
    p=head.next
    while p!=None:
        print(p.sno,p.sname)
        p=p.next

def keepSorted(n):                  #在输入数据的过程中保持链表有序
    head=Node()                #建立头结点
    for i in range(n):              #循环n次
        t=input().split()         #输入学号、姓名
        q=Node(t[0],t[1])                 #建立新结点
        p=head                      #p指向头结点
        while p.next!=None:         #当p尚未达最后一个结点
            if p.next.sno>=q.sno:   #若p结点的后继的学号大于或等于新结点q的学号,则结束循环
                break
            p=p.next                #p指向下一个结点
        q.next=p.next               #新结点q链接到p.next结点之前
        p.next=q                    #新结点q链接到p结点之后        
    return head                     #返回头结点

    
T=int(input())
for t in range(T):
    n=int(input())
    h=keepSorted(n)
    output(h)


习题7.2.1 输出链表偶数结点

先输入N个整数,按照输入的顺序建立链表。然后遍历并输出偶数位置上的结点信息。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试的第一行输入整数的个数N(1≤N≤100);第二行依次输入N个整数。

输出格式:
对于每组测试,输出该链表偶数位置上的结点的信息。

输入样例:
2
8
12 56 4 6 55 15 33 62
3
1 2 1
输出样例:
56 6 15 62
2

点击查看代码
class Node:                 #定义类
    def __init__(self, data):
        self.data=data
        self.next=None

def createByTail(a):        #创建顺序链表
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

def output(head):           #遍历链表,输出偶数结点数据
    p=head.next
    cnt=0
    while p!=None:
        cnt+=1
        if cnt%2==0:
            if cnt!=2:
                print(' ',end='')
            print(p.data,end='')
        p=p.next
    print()

T=int(input())
for t in range(T):
    n=int(input())
    a=list(map(int,input().split()))
    h=createByTail(a)
    output(h)

习题7.2.2 使用链表进行逆置

对于输入的若干学生的信息,利用链表进行储存,并将学生的信息逆序输出。
要求将学生的完整信息存放在链表的结点中。通过链表的操作完成信息的逆序输出。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试数据首先输入一个正整数n,表示学生的个数(1≤n≤100);然后是n行信息,分别表示学生的姓名(不含空格且长度不超过10的字符串)和年龄(正整数)。

输出格式:
对于每组测试,逆序输出学生信息(参看输出样例)。

输入样例:
1
3
Zhangsan 20
Lisi 21
Wangwu 20
输出样例:
Wangwu 20
Lisi 21
Zhangsan 20

点击查看代码
class Node:                 #定义类
   def __init__(self,name,age):
        self.name=name
        self.age=age
        self.next=None
        
def createByFront(n):
    head=Node("",0)
    for i in range(n):
        t=input().split()
        t[1]=int(t[1])
        p=Node(t[0],t[1])
        p.next=head.next
        head.next=p
    return head
    
def output(head):           #遍历链表
    p=head.next
    while p!=None:
        print(p.name,p.age)
        p=p.next

T=int(input())
for t in range(T):
    n=int(input())
    h=createByFront(n)
    output(h)
# class Node:                 #定义类
#     def __init__(self, name, age):
#         self.name=name
#         self.age=age
#         self.next=None

# def createByTail(n):        #创建顺序链表
#     head=Node("",0)
#     tail=head
#     for i in range(n):
#         name,age=input().split()
#         p=Node(name,int(age))
#         tail.next=p
#         tail=p
#     return head

# def reverse(head):          #head为头结点
#     p=head.next             #p“指向”第一个数据结点
#     head.next=None          #头结点指针域置为空值
#     while p!=None:          #当链表还没有扫描结束
#         q=p                 #q“指向”结点p(原链表的第一个数据结点)
#         p=p.next            #p“指向”下一个结点
#         q.next=head.next    #结点q链接到第一个数据结点(第一次为None)之前
#         head.next=q         #结点q链接到头结点之后

# def output(head):           #遍历链表
#     p=head.next
#     while p!=None:
#         print(p.name,p.age)
#         p=p.next

# T=int(input())
# for t in range(T):
#     n=int(input())
#     h=createByTail(n)
#     reverse(h)
#     output(h)

习题7.2.3 链表排序

请以单链表存储n个整数,并实现这些整数的非递减排序。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入两行,第一行输入一个整数n(0<n<100),第二行输入n个整数。

输出格式:
对于每组测试,输出排序后的结果,每两个数据之间留一个空格。

输入样例:
6
3 5 1 2 8 6
输出样例:
1 2 3 5 6 8

点击查看代码
class Node:                 #定义类
    def __init__(self, data):
        self.data=data
        self.next=None

def createByTail(a):        #创建顺序链表
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

def output(head):           #遍历链表
    p=head.next
    cnt=0
    while p!=None:
        cnt+=1
        if cnt>1:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()

def sort(head):             #链表冒泡排序
    p=head.next
    while p.next!=None:
        q=p.next
        while q!=None:
            if p.data>q.data:
                p.data,q.data=q.data,p.data
            q=q.next
        p=p.next

try:
    while True:
        n=int(input())
        a=map(int,input().split())
        a=list(a)
        h=createByTail(a)
        sort(h)
        output(h)
except EOFError:pass

习题7.2.4 合并升序单链表

各依次输入递增有序若干个不超过100的整数,分别建立两个单链表,将这两个递增的有序单链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。合并后的单链表中不允许有重复的数据。然后输出合并后的单链表。

输入格式:
首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先在第一行输入数据个数n;再在第二行和第三行分别输入n个依次递增有序的不超过100的整数。

输出格式:
对于每组测试,输出合并后的单链表,每两个数据之间留一个空格。

输入样例:
1
5
1 3 5 7 9
4 6 8 10 12
输出样例:
1 3 4 5 6 7 8 9 10 12

点击查看代码
class Node:                 #定义类
    def __init__(self, data):
        self.data=data
        self.next=None

def createByTail(a):        #创建顺序链表
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

def output(head):           #遍历链表
    p=head.next
    cnt=0
    while p!=None:
        cnt+=1
        if cnt>1:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()

def merge(ha,hb):           #合并单链表
    p=ha.next
    q=hb.next
    hc=ha
    tail=hc
    while p!=None and q!=None:
        if p.data<q.data:
            tail.next=p
            tail=p 
            p=p.next           
        elif p.data>q.data:
            tail.next=q
            tail=q
            q=q.next
        else:
            tail.next=p
            tail=p 
            p=p.next
            q=q.next
    if p!=None:
        tail.next=p
    else:
        tail.next=q
    return hc

T=int(input())
for t in range(T):
    n=int(input())
    a=list(map(int,input().split()))
    h1=createByTail(a)
    b=list(map(int,input().split()))
    h2=createByTail(b)
    h=merge(h1,h2)
    output(h)
        

习题7.2.5 拆分单链表

输入若干个(最多20个)不含整数0的绝对值不超过100的整数,先建立单链表A,然后将单链表A分解为两个具有相同结构的链表B、C,其中B链表的结点为A链表中值小于零的结点,而C链表的结点为A链表中值大于零的结点。请尽量利用原有结点空间。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据在一行上输入数据个数n(2≤n≤20)及n个不含整数0且绝对值不超过100的整数。

输出格式:
对于每组测试,分两行按原数据顺序输出链表B和C,每行中的每两个数据之间留一个空格。

输入样例:
1
10 49 53 -26 79 -69 -69 18 -96 -11 68
输出样例:
-26 -69 -69 -96 -11
49 53 79 18 68

点击查看代码
class Node:                 #定义类
    def __init__(self, data):
        self.data=data
        self.next=None

def createByTail(a):        #创建顺序链表
    head=Node(-1)
    tail=head
    for i in range(len(a)):
        p=Node(a[i])
        tail.next=p
        tail=p
    return head

def output(head):           #遍历链表
    p=head.next
    cnt=0
    while p!=None:
        cnt+=1
        if cnt>1:
            print(' ',end='')
        print(p.data,end='')
        p=p.next
    print()

#拆分链表,负数保留在原链表头结点所在的链表,整数从原链表中删除并链接到新链表的尾结点之后
def detach(ha):
    hb=Node(-1)
    p=ha
    q=hb    
    while p.next!=None:
        if p.next.data<0:            
            p=p.next           
        elif p.next.data>0:
            q.next=p.next
            q=q.next
            p.next=p.next.next            
    q.next=None
    return hb

T=int(input())
for t in range(T):
    a=list(map(int,input().split()))
    n=a[0]
    a=a[1:]
    h1=createByTail(a)
    h2=detach(h1)
    output(h1)
    output(h2)
        

第八章

例8.1.1 铺满方格

有一个1×n的长方形,由边长为1的n个方格构成,例如,当n=3时为1×3的方格长方形如下图所示。求用1×1、1×2、1×3的骨牌铺满方格的方案总数。
image

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n(1≤n≤50)。

输出格式:
对于每组测试,输出一行,包含一个整数,表示用骨牌铺满方格的方案总数。

输入样例:
3
输出样例:
4

点击查看代码
N=50
a=[0]*(N+1)
a[1]=1
a[2]=2
a[3]=4
for i in range(4,N+1):
    a[i]=a[i-1]+a[i-2]+a[i-3]

try:
    while True:
        n=int(input())
        print(a[n])
except EOFError:pass

例8.1.2 数塔

数塔如图所示,若每一步只能走到相邻的结点(图中有数字的方格),则从最顶层走到最底层所经过的所有结点的数字之和最大是多少?测试数据保证结果处于int范围内。
image

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据第一行输入一个整数n(1≤n≤100),表示数塔的高度,接下来输入n行表示数塔的数字,其中第i行有i个整数。

输出格式:
对于每组测试,输出一行,包含一个整数,表示从最顶层走到最底层可能得到的最大和。

输入样例:
1
5
6
3 9
7 1 2
2 5 0 9
8 4 7 1 6
输出样例:
32

点击查看代码
def solve(a,n):
    for i in range(n-2,-1,-1):
        for j in range(0,i+1):
            a[i][j]+=max(a[i+1][j],a[i+1][j+1])
    print(a[0][0])

T=int(input())
for i in range(T):
    n=int(input())
    a=[]
    for i in range(n):
        t=list(map(int,input().split()))
        a.append(t)
    solve(a,n)

例8.1.3 最长有序子序列

image

例如,(1,3,5)、(3,5,8)、(1,3,5,9)等都是序列 (1,7,3,5,9,4,8) 的有序子序列;而(1,3,5,9)、(1,3,5,8)、(1,3,4,8)都是序列 (1,7,3,5,9,4,8)的一个最长有序子序列,长度为4。

请编写程序,求出给定数字序列中的最长有序子序列的长度。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据第一行输入一个整数 n(1≤n≤1000),第二行输入n个整数,数据范围都在[0,10000],数据之间以一个空格分隔。

输出格式:
对于每组测试,输出n个整数所构成序列的最长有序子序列的长度。每两组测试的输出之间留一个空行。

输入样例:
1
7
1 7 3 5 9 4 8
输出样例:
4

点击查看代码
def los(a):
    n=len(a)
    f=[1]*n
    for i in range(1,n):
        for j in range(0,i):
            if a[j]<a[i] and f[j]+1>f[i]:
                f[i]=f[j]+1
    return max(f)
T=int(input())
for t in range(T):
    n=int(input())
    a=list(map(int,input().split()))
    if t>0: print()
    print(los(a))

例8.1.4 0-1背包问题

给定n种物品(每种仅一个)和一个容量为c的背包,要求选择物品装入背包,使得装入背包中物品的总价值最大。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据输入3行,第1行为两个整数n(1≤n≤400)和c (1≤c≤1500),分别表示物品数量与背包容量,第二行为n个物品的重量wi(1≤i≤n),第三行为这n个物品的价值vi(1≤i≤n)。物品重量、价值都为整数。

输出格式:
对于每组测试,在一行上输出一个整数,表示装入背包的最大总价值(结果保证在int范围内)。

输入样例:
4 9
2 3 4 5
3 4 5 7
输出样例:
12

点击查看代码
def knapsack(c,w,v):
    n=len(w)
    f=[0]*(c+1)
    for i in range(n):
        for j in range(c,w[i]-1,-1):
            f[j]=max(f[j],f[j-w[i]]+v[i])
    print(f[c])

try:
    while True:
        n,c=map(int,input().split())
        w=list(map(int,input().split()))
        v=list(map(int,input().split()))
        knapsack(c,w,v)
except EOFError:pass

例8.2.1 奇数平方和

image

输入格式:
测试数据有多组,处理到文件尾。每组测试数据输入一个奇数n。

输出格式:
对于每组测试,输出奇数的平方和。

输入样例:
3
输出样例:
10

点击查看代码
try:
    while True:
        n=int(input())
        res=n*(n+1)*(n+2)//6     #使用奇数平方和公式
        print(res)
except EOFError:pass

例8.2.2 幂次取余

image

给定三个正整数A,B和C,求A
B
mod C的结果,其中mod表示求余数。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据输入三个正整数A,B,C(A,B,C≤1000000)。

输出格式:
对于每组测试,输出计算后的结果,每组测试的输出占一行。

输入样例:
2
3 3 5
4 4 6
输出样例:
2
4

点击查看代码
def f(m,n,k):                   #用快速幂求m^n%k
    if n==0:
        return 1
    else:
        t=f(m,n//2,k)%k         #递归调用,用t暂存递归调用的结果
        if n%2==0:
            return t*t%k
        else:
            return t*t*m%k

T=int(input())
for t in range(T):
    a,b,c=map(int,input().split())
    print(f(a,b,c))

例8.2.3 大菲波数

斐波那契数列是这样定义的:f(1)=1;f(2)=1;f(n)=f(n-1)+f(n-2)(n>=3)。所以1,1,2,3,5,8,13……就是斐波那契数列。输入一个整数n,求斐波那契数列的第n项。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后输入T组测试数据。每组测试数据输入一个整数n(1≤n≤1000)。

输出格式:
对于每组测试,在一行上输出斐波那契数列的第n项f(n)。

输入样例:
2
105
4
输出样例:
3928413764606871165730
3

点击查看代码
n=1000
a=[0]*(n+1)                 	#一次性把所有的项计算出来存放在列表中,下标从1开始用
a[1]=1				#第1项为1
a[2]=1				#第2项为1
for i in range(3,n+1):		#从第3项开始等于前两项之和
    a[i]=a[i-1]+a[i-2]

T=int(input())
for i in range(T):
    n=int(input())    
    print(a[n])             	#输入n后直接取下标为n的列表元素值

例8.2.4 大数和

给定一些大整数,请计算其和。

输入格式:
测试数据有多组。对于每组测试数,首先输入一个整数n(n≤100),接着输入n个大整数(位数不超过200)。若n=0则表示输入结束。

输出格式:
对于每组测试,输出n个整数之和,每个结果单独占一行。

输入样例:
2
43242342342342
-1234567654321
0
输出样例:
42007774688021

点击查看代码
while True:
    n=int(input())
    if n==0:break
    sum=0 			#累加单元清0
    for i in range(n):
        t=int(input()) 		#输入的数字字符串转换为整数
        sum+=t			#逐个累加输入的数据
    print(sum)

例8.2.5 n!

输入一个非负整数n,求n!。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据输入一个整数n(0≤n≤10000)。

输出格式:
对于每组测试,输出整数n的阶乘。

输入样例:
5
输出样例:
120

点击查看代码
n=10000
a=[0]*(n+1)				#创建全0列表
a[0]=1					#0!=1
a[1]=1					#1!=1
for i in range(2,n+1): 		        #i!=(i-1)!*i
    a[i]=a[i-1]*i

try:
    while True:
        n=int(input())
        print(a[n])			#输入数据n后直接从列表取得结果a[n]并输出
except EOFError:pass

例8.4.1 畅通工程

某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?

输入格式:
测试数据有多组。每组测试数据的第一行输入两个正整数,分别是城镇数目N(N<1000)和道路数目M;随后输入M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说

3 3

1 2

1 2

2 1

这种输入也是合法的。

当仅输入N为0时,表示输入结束。

输出格式:
对于每组测试,在一行上输出最少还需要建设的道路数目。

输入样例:
4 2
1 3
4 3
0
输出样例:
1

点击查看代码
def dfs(s,n):               #连通图的深搜,s是起点,n是顶点总数
    visited[s]=True         #起点标记为已访问
    for i in range(n):      #逐个点检查,若该点与s之间有边且未访问过,则从该点出发继续深搜
        if mat[s][i]==1 and visited[i]==False:
            dfs(i,n)

while True:
    s=input()               #输入字符串,若为0则结束循环
    if s=="0":
        break
    n,m=map(int,s.split())  #输入的字符串分割为顶点数n和边数m
    visited=[False]*n       #标记列表
    #构造全0的邻接矩阵
    mat=[[0]*n for i in range(n)]
    for i in range(m):      #根据输入的边,置邻接矩阵的相应元素为1
        a,b=map(int,input().split())
        a-=1
        b-=1
        mat[a][b]=mat[b][a]=1
    cnt=0                   #计数器cnt用于统计子图数,初值置为0
    for i in range(n):      #逐个点检查,若该点未访问过,则从该点出发继续深搜,且子图数加1
        if visited[i]==False:
            dfs(i,n)
            cnt+=1
    print(cnt-1)            #需修的道路数为子图数减1


例8.4.2 迷宫问题之能否走出

image

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入2个数n,m(0<n,m≤100),代表迷宫的高和宽,然后n行,每行m个字符,各字符的含义如下:
'S'代表小明现在所在的位置;'T'代表迷宫的出口;'#'代表墙,不能走;'.'代表路,可以走。

输出格式:
对于每组测试,若能成功脱险,输出“YES”,否则输出“NO”。引号不必输出。

输入样例:

4 4
S...
#..#
..#.
...T

输出样例:
YES

点击查看代码
dir=[[0,1],[1,0],[0,-1],[-1,0]]     #方向列表
class Pos:
    def __init__(self,x,y):         #成员x,y,分别表示行坐标、列坐标
        self.x=x
        self.y=y

def check(x,y):                     #检查(x,y)是否是m行n列迷宫中的可走点
    if x<0 or x>=m or y<0 or y>=n:  #若不在迷宫中,则不可走
        return False
    if visited[x][y]==True:         #若已走过,则不可走
        return False
    if mat[x][y]=='#':              #若遇到特殊字符#,则不可走
        return False
    return True

def dfs(s,t):                       #深搜,s是起点,t是终点
    if s.x==t.x and s.y==t.y:       #若找到终点,则标记变量success置为True并返回
        global success
        success=True
        return
    visited[s.x][s.y]=True          #起点标记为已访问
    for i in range(4):              #右、下、左、上四个相邻点逐个检查,若可走,则再从该点开始深搜
        newx=s.x+dir[i][0]
        newy=s.y+dir[i][1]
        if check(newx,newy)==True:
            dfs(Pos(newx,newy),t)

try:
    while True:
        m,n=map(int,input().split())#输入的字符串分割为行数m和列数n
        visited=[]                  #标记列表
        mat=[]                      #迷宫列表
        for i in range(n):          #构造全'0'的迷宫列表,全False的标记列表
            t=['0']*n
            mat.append(t)
            t=[False]*n
            visited.append(t)
        s=Pos(0,0)                  #s是起点,坐标点设为(0,0)
        t=Pos(m-1,n-1)              #t是终点,坐标点设为(m-1,n-1)
        for i in range(m):          #输入m行,找到起点、终点字符并记录各自的位置
            mat[i]=input()
            for j in range(n):
                if mat[i][j]=='S':
                    s.x=i
                    s.y=j
                elif mat[i][j]=='T':
                    t.x=i
                    t.y=j
        success=False	            #全局变量置为False
        dfs(s,t)                    #调用深搜
        if success==True:
            print("YES")
        else:
            print("NO")
except EOFError:pass

例8.4.3 迷宫问题之几种走法

image

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入2个整数n,m(0<n,m≤100),代表迷宫的高和宽,然后n行,每行m个字符,各字符的含义如下:
'S'代表小明现在所在的位置;'T'代表迷宫的出口;'#'代表墙,不能走;'.'代表路,可以走。

输出格式:
对于每组测试,输出一共有多少种不同的走法,若不能走出则输出impossible。

输入样例:

4 4
S...
#..#
..#.
...T

输出样例:
4

点击查看代码
dir=[[0,1],[1,0],[0,-1],[-1,0]]     #方向列表
class Pos:
    def __init__(self,x,y):         #成员x,y,分别表示行坐标、列坐标
        self.x=x
        self.y=y

def check(x,y):                     #检查(x,y)是否是m行n列迷宫中的可走点
    if x<0 or x>=m or y<0 or y>=n:  #若不在迷宫中,则不可走
        return False
    if visited[x][y]==True:         #若已走过,则不可走
        return False
    if mat[x][y]=='#':              #若遇到特殊字符#,则不可走
        return False
    return True

def dfs(s,t):                       #深搜,s是起点,t是终点
    if s.x==t.x and s.y==t.y:       #若找到终点,则计数器变量增1
        global cnt
        cnt+=1

    visited[s.x][s.y]=True          #起点标记为已访问
    for i in range(4):              #右、下、左、上四个相邻点逐个检查,若可走,则再从该点开始深搜
        newx=s.x+dir[i][0]
        newy=s.y+dir[i][1]
        if check(newx,newy)==True:
            dfs(Pos(newx,newy),t)
    visited[s.x][s.y]=False         #恢复现场,以便求其他解
try:
    while True:
        m,n=map(int,input().split())#输入的字符串分割为行数m和列数n
        visited=[]                  #标记列表
        mat=[]                      #迷宫列表
        for i in range(n):          #构造全'0'的迷宫列表,全False的标记列表
            t=['0']*n
            mat.append(t)
            t=[False]*n
            visited.append(t)
        s=Pos(0,0)                  #s是起点,坐标点设为(0,0)
        t=Pos(m-1,n-1)              #t是终点,坐标点设为(m-1,n-1)
        for i in range(m):          #输入m行,找到起点、终点字符并记录各自的位置
            mat[i]=input()
            for j in range(n):
                if mat[i][j]=='S':
                    s.x=i
                    s.y=j
                elif mat[i][j]=='T':
                    t.x=i
                    t.y=j
        cnt=0	                    #全局变量cnt置为0
        dfs(s,t)                    #调用深搜函数
        if cnt>0:                   #若cnt==0,则走不通,否则输出走法数
            print(cnt)
        else:
            print("impossible")
except EOFError:pass


例8.4.4 迷宫问题之最短步数

image

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入2个数n,m(0<n,m≤100),代表迷宫的高和宽,然后n行,每行m个字符,各字符的含义如下:
'S'代表小明现在所在的位置;'T'代表迷宫的出口;'#'代表墙,不能走;'.'代表路,可以走。

输出格式:
对于每组测试,输出走出迷宫的最少时间,若不能走出则输出impossible。

输入样例:

4 4
S...
#..#
..#.
...T

输出样例:
6

点击查看代码
from queue import Queue             #从队列queue导入队列类Queue
dir=[[0,1],[1,0],[0,-1],[-1,0]]     #方向列表
Max=100*100*10

class Pos:
    #x,y,steps等三个成员,分别表示行坐标、列坐标及从起点走到该点的步数
    def __init__(self,x,y,steps):
        self.x=x
        self.y=y
        self.steps=steps

def bfs(s,t):                                       #广搜,s是起点,t是终点
    global res                                      #全局变量res存放最终结果
    q=Queue()                                       #创建空队列    
    q.put(s)                                        #起点入队
    while q.empty()==False:                         #当队列非空
        f=q.get()                                   #取队头元素,置于f中
        if f.x==t.x and f.y==t.y:                   #若找到终点,则比较其步数(当前结果)与res的大小
            if f.steps<res:                         #若当前结果小于res,则更新res
                res=f.steps
        for i in range(4):                          #右、下、左、上四个相邻点逐个检查
            p=Pos(f.x+dir[i][0],f.y+dir[i][1],f.steps+1)
            if p.x<0 or p.x>=m or p.y<0 or p.y>=n:  #若不在迷宫中,则不可走
                continue
            if mat[p.x][p.y]=='#':                  #若遇到特殊字符#,则不可走
               continue
            if mat[p.x][p.y].isdigit():
                p.steps+=int(mat[p.x][p.y])
            if p.steps>=steps[p.x][p.y]:            #若步数不小于原来的步数,则不走
                continue
            steps[p.x][p.y]=p.steps
            q.put(p)
try:
    while True:
        m,n=map(int,input().split())                #输入的字符串分割为行数m和列数n
        steps=[[Max]*n for i in range(n)]           #步数列表,初始化为全Max
        mat=[['0']*n for i in range(n)]             #迷宫列表,初始化为全'0'
        s=Pos(0,0,0)                                #s是起点
        t=Pos(m-1,n-1,0)                            #t是终点
        for i in range(m):                          #输入,记录起点、终点的位置
            mat[i]=input()
            for j in range(n):
                if mat[i][j]=='S':
                    s.x=i
                    s.y=j
                elif mat[i][j]=='T':
                    t.x=i
                    t.y=j
        res=Max
        bfs(s,t)
        if res==Max:
            print("impossible")
        else:
            print(res)
except EOFError:pass

习题8.2.2 最少拦截系统

已知n个依次飞来导弹的高度,请计算最少需要多少套这种拦截系统才能拦截所有导弹。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据首先输入导弹总个数n(小于100的正整数),接着输入n个导弹依次飞来的高度(不大于30000的正整数,用空格分隔)。

输出格式:
对于每组测试,输出拦截所有导弹最少需要多少套这种拦截系统。

输入样例:
8 6 5 7 2 3 8 1 4
输出样例:
3

点击查看代码
def los(a,n):
    res=[1]*n
    for i in range(1,n):
        for j in range(i-1,-1,-1):
            if a[i]>a[j] and res[j]+1>res[i]:
                res[i]=res[j]+1
    return max(res)
try:
    while True:
        a=list(map(int,input().split()))
        n=a[0]
        a=a[1:]
        print(los(a,n))
except EOFError:pass

习题8.2.3 最大连续子序列

image

输入格式:
测试数据有多组。每组测试数据输入两行,第一行给出一个正整数K(0<K<10000),第二行给出K个整数,中间用空格分隔。当K为0时,输入结束。

输出格式:
对于每组测试,在一行里输出最大和、最大连续子序列的第一个和最后一个元素,数据之间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个。若所有K个元素都是负数,则定义其最大和为0,再输出整个序列的第一个和最后一个元素。

输入样例:
6
-2 11 -4 13 -5 -2
10
-1 -2 -7 -3 -4 -5 -6 -4 -3 -8
0
输出样例:
20 11 13
0 -1 -8

点击查看代码
def f(a,begin,end):
    curBegin=0    
    n=len(a)
    maxSum=-1
    curSum=0
    for i in range(n):        
        curSum=curSum+a[i]
        if curSum<0:
            curSum=0
            curBegin=i+1
        elif curSum>maxSum:
            maxSum=curSum
            end=i
            begin=curBegin
    if maxSum==-1:maxSum=0
    print(maxSum,a[begin],a[end])

while True:
    n=int(input())
    if n==0: break
    a=list(map(int,input().split()))
    f(a,0,n-1)

posted @   Trouvaille_fighting  阅读(2488)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航