PAT乙级python编程练习(二)
1006 换个格式输出整数
让我们用字母B来表示“百”、字母S表示“十”,用“12…n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数。例如234应该被输出为BBSSS1234,因为它有2个“百”、3个“十”、以及个位的4。
输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000)。
输出格式:每个测试用例的输出占一行,用规定的格式输出n。
输入样例1:
234
输出样例1:
BBSSS1234
输入样例2:
23
输出样例2:
SS123
思路及注意点
- 先计算出输入数字的百位、十位和个位,然后依次输出百位数字个数的‘B’,十位数字个数的‘S’,最后输出1~个位数字
- 代码中[None]*3不能写作[]*3.
>>> l = [] * 3
>>> l[0]
Traceback (most recent call last):
File "<ipython-input-126-44e56f8a6e9f>", line 1, in <module>
l[0]
IndexError: list index out of range
>>> l = [None] * 3
>>> print(l[0])
None
代码
n = int(input())
l = [None] * 3
l[0] = n // 100
l[1] = n % 100 //10
l[2] = n % 10
for i in range(l[0]):
print('B', end='')
for i in range(l[1]):
print('S', end='')
for i in range(l[2]):
print(str(i+1), end='')
运行结果
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 23 ms | 3056KB |
1 | 答案正确 | 24 ms | 3040KB |
2 | 答案正确 | 25 ms | 3056KB |
3 | 答案正确 | 23 ms | 3076KB |
4 | 答案正确 | 23 ms | 3056KB |
5 | 答案正确 | 27 ms | 3056KB |
6 | 答案正确 | 24 ms | 3184KB |
7 | 答案正确 | 24 ms | 3056KB |
8 | 答案正确 | 23 ms | 3076KB |
1007 素数对猜想
让我们定义 为 ,其中 是第 个素数。显然有 ,且对于 有 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<10^5 ),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
方法一
思路及注意点
- 经典的判断素数的方法:从3开始,若该数能被[2,它的平方根]区间的任一整数整除,则它不是素数。这种方法输入10^5在本地跑耗时大概599ms,最后一个测试点超时。
- 对于计算程序的运行时间,可以导入标准库的time模块,分别在开始和结尾利用time.time()记录时刻,两者相减就是程序运行时间。注意对于有输入的程序,这里把第一次计时放在input后。
代码
# 599ms
from math import sqrt
#import time
N = int(input())
#t1 = time.time()
primeL = [] if N < 2 else [2]
count = 0
for i in range(3,N+1):
end = int(sqrt(i)) + 2
for j in range(2,end):
if i % j == 0:
break
if j == end-1:
if i - primeL[-1] == 2:
count += 1
primeL.append(i)
print(count)
#t2 = time.time()
#print(t2-t1)
方法二
思路及注意点
- 利用一个列表记录素数判断结果,对于任意大于1的数i,i的(2,3,4,…)倍都不是素数。
- 输入10^5在本地跑大概耗时250ms,最后一个测试点超时。
代码
# 250ms
#import time
N = int(input())
#t1 = time.time()
prime = [True]*(N+1)
for i in range(2, N//2+1):
s = i+i
while s<=N:
prime[s] = False
s += i
cnt = 0
for i in range(5, N+1):
if prime[i] and prime[i-2]:
cnt += 1
print(cnt)
#t2 = time.time()
#print(t2-t1)
方法三
思路及注意点
- 方法三属于方法二的优化,在方法二中,很多数会被重复验证,比如8在排除2的倍数时已经判定不是素数,但还会在排除4的倍数的时候再判定一次。因此方法三中在记录素数结果的列表中,按顺序取第一个仍记录为1(素数)的数,把后续列表中下标为该数的倍数的全部设置为0(非素数),然后再从整个列表中取第一个记录为1的数,依次循环。
- 输入10^5在本地跑大概耗时46ms,能过所有测试点。
代码
# 46ms
#import time
a = int(input())
#t1 = time.time()
def prime(n,result):
flag = [1]*(n+2)
p=2
while(p<=n):
result.append(p)
for i in range(2*p,n+1,p):
flag[i] = 0
while 1:
p += 1
if(flag[p]==1):
break
result = []
prime(a,result)
num = 0
for i in range(len(result)-1):
if (result[i+1]-result[i]==2):
num+=1
print(num)
#t2 = time.time()
#print(t2-t1)
运行结果
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 23 ms | 3152KB |
1 | 答案正确 | 24 ms | 3184KB |
2 | 答案正确 | 27 ms | 3176KB |
3 | 答案正确 | 23 ms | 3076KB |
4 | 答案正确 | 23 ms | 3064KB |
5 | 答案正确 | 74 ms | 4260KB |
1008 数组元素循环右移问题
一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A~0~ A~1~……A~N-1~)变换为(A~N-M~ …… A~N-1~ A~0~ A~1~……A~N-M-1~)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。
输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
思路及注意点
- 双端队列deque有一个rotate方法正好解决的是数组左移右移问题。
>>> from collections import deque
>>> q = deque(range(5))
>>> q
deque([0,1,2,3,4])
>>> q.rotate(3)
>>> q
deque([2,3,4,0,1])
>>> q.rotate(-1)
>>> q
deque([3,4,0,1,2])
代码
from collections import deque
n, m = input().split()
m = int(m)
s = input()
q = deque(s.split())
q.rotate(m)
p = list(q)
for i in range(len(p)):
if i == len(p)-1:
print(p[i], end='')
else:
print(p[i], end=' ')
运行结果
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 27 ms | 3436KB |
1 | 答案正确 | 26 ms | 3436KB |
2 | 答案正确 | 26 ms | 3456KB |
3 | 答案正确 | 27 ms | 3496KB |
4 | 答案正确 | 27 ms | 3436KB |
1009 说反话
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有多余的空格。
输出格式:每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
思路及注意点
- emmm这道题对python来说好像没啥意思。。。就是输入以空格分割字符串然后再反向输出。
代码
s = input()
l = s.split()
for i in range(len(l)):
if i == len(l)-1:
print(l[0], end='')
else:
print(l[len(l)-i-1], end=' ')
运行结果
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 24 ms | 3056KB |
1 | 答案正确 | 24 ms | 3056KB |
2 | 答案正确 | 23 ms | 3056KB |
3 | 答案正确 | 23 ms | 3056KB |
1010 一元多项式求导
设计函数求一元多项式的导数。(注:x^n^(n为整数)的一阶导数为n*x^n-1^。)
输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是0,但是表示为“0 0”。
输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
思路及注意点
- 注意指数不一定连续的,也不一定有0次项
- 注意指数可以是负数,因此不能判断到0即止
- 这里用到了字符串的strip方法,去掉了首尾的空格。之前一直用的print(‘…’, end=”)来控制最后的空格。
代码
a, res = list(map(int, input().split())), ""
if len(a)==2 and a[1]==0:
print("0 0")
else:
for i in range(0, len(a), 2):
if a[i + 1] != 0:
res += str(a[i] * a[i + 1]) + " " + str(a[i + 1] - 1) + " "
print(res.strip())
运行结果
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 23 ms | 3056KB |
1 | 答案正确 | 23 ms | 3076KB |
2 | 答案正确 | 23 ms | 3056KB |
3 | 答案正确 | 24 ms | 3140KB |
4 | 答案正确 | 22 ms | 3076KB |