PAT乙级python编程练习(四)

PAT乙级python编程练习(四)

1016 部分A+B

正整数 A 的“DA(为 1 位整数)部分”定义为由 A 中所有 DA组成的新整数 PA。例如:给定 A=3862767,DA=6,则 A 的“6 部分”PA是 66,因为 A 中有 2 个 6。

现给定 A、DA​​ 、B、DB​​ ,请编写程序计算 PA​​ +P​B​​ 。

输入格式:
输入在一行中依次给出 A、D​A​​ 、B、D​B​​ ,中间以空格分隔,其中 0 < A,B < 10^10​​ 。

输出格式:
在一行中输出 P​A​​ +P​B​​ 的值。

输入样例 1:

3862767 6 13530293 3

输出样例 1:

399

输入样例 2:

3862767 1 13530293 8

输出样例 2:

0

思路及注意点

  1. 代码中 pa = pa*10 + da 要比 pa = pa + da * 10 ** i 要好。

代码

s = input().split()
pa = pb = 0
da = int(s[1])
db = int(s[3])
for c in s[0]:
    if c == s[1]:
        pa = pa*10 + da
for c in s[2]:
    if c == s[3]:
        pb = pb*10 + db
print(pa+pb)

运行结果

测试点结果耗时内存
0答案正确23 ms3056KB
1答案正确22 ms3064KB
2答案正确22 ms3076KB
3答案正确22 ms3168KB
4答案正确22 ms3056KB

1017 A除以B

本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数。你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立。

输入格式:
输入在一行中依次给出 A 和 B,中间以 1 空格分隔。

输出格式:
在一行中依次输出 Q 和 R,中间以 1 空格分隔。

输入样例:

123456789050987654321 7

输出样例:

17636684150141093474 3

思路及注意点

  1. 对于输入的数从高位到低位,依次加上之前的余数*10,再去整除B,得到的商为该位的输出,余数*10加到下一位的计算中。
  2. 最后结果若最高为为0,则忽略这位的0输出。

代码

s = input().split()
d = list(map(str, range(10)))
a = list(map(int, s[0]))
b = int(s[1])

result = ''
r = 0
for x in a:
    num = r*10+x
    q = num // b
    r = num % b
    result += d[q]
if result[0] == '0' and len(result) > 1:
    result = result[1:]
print(result, r)

运行结果

测试点结果耗时内存
0答案正确24 ms3056KB
1答案正确23 ms3156KB
2答案正确22 ms3056KB
3答案正确25 ms3120KB
4答案正确23 ms3076KB

1018 锤子剪刀布

大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

输入格式:

输入第1行给出正整数N(<=10^5^),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。

输出格式:

输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。

输入样例:

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

输出样例:

5 3 2
2 3 5
B B

思路及注意点

  1. 用一个count列表来记录甲的胜平负次数,乙的只需要反向输出即可。
  2. 用两个字典分别存储甲乙三种手势的获胜次数。排序用到了前面博客提到过的operator模块的itemgetter方法,先根据获胜次数排序,再根据字母序排序。
  3. 最后一个测试点运行超时,目前我还没找到解决方法。。。求助大佬!(通过1005和这题,深深感觉到这套题在运行时间限制上对python的不友好【捂脸.jpg】,明明和c++一样的算法python运行时间能长好多。虽然说有些题目python能很快解决,比如大整数运算、正则表达式什么的。总之有得必有失。)

代码

#from time import time
n = int(input())
#t1 = time()
from operator import itemgetter
d1 = {'C':0, 'J':0, 'B':0}
d2 = {'C':0, 'J':0, 'B':0}
#0 胜   1 平    2 负
d = {'C C':1, 'C J':0, 'C B':2, 
    'J C':2, 'J J':1, 'J B':0, 
    'B C':0, 'B J':2, 'B B':1}
count = [0] * 3
while n:
    n -= 1
    s = input()
    idx = d[s]
    count[idx] += 1
    if idx == 0:
        d1[s[0]] -= 1
    elif idx == 2:
        d2[s[2]] -= 1
print(count[0], count[1], count[2])
print(count[2], count[1], count[0])
item1, item2 = list(d1.items()), list(d2.items())
item1.sort(key=itemgetter(1,0))
item2.sort(key=itemgetter(1,0))
print(item1[0][0], item2[0][0])
#t2 = time()
#print(t2-t1)

运行结果

测试点结果耗时内存
0答案正确25 ms3192KB
1答案正确24 ms3204KB
2答案正确24 ms3204KB
3答案正确24 ms3168KB
4答案正确23 ms3204KB
5运行超时0 ms0KB

1019 数字黑洞

给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。

例如,我们从6767开始,将得到

7766 - 6677 = 1089\ 9810 - 0189 = 9621\ 9621 - 1269 = 8352\ 8532 - 2358 = 6174\ 7641 - 1467 = 6174\ … …

现给定任意4位正整数,请编写程序演示到达黑洞的过程。

输入格式:

输入给出一个(0, 10000)区间内的正整数N。

输出格式:

如果N的4位数字全相等,则在一行内输出“N - N = 0000”;否则将计算的每一步在一行内输出,直到6174作为差出现,输出格式见样例。注意每个数字按4位数格式输出。

输入样例1:

6767

输出样例1:

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174

输入样例2:

2222

输出样例2:

2222 - 2222 = 0000

思路及注意点

  1. 最初的输入可能不足四位。步骤中不足四位的均要填补0.
  2. 用到了字符串的join方法,join其实是split的逆方法
>>> ''.join(['1','2','3'])
'123'

>>> '+'.join(['1','2','3'])
'1+2+3'

代码

s = input()
if len(s) < 4:
    s += '0' * (4-len(s))
n1 = int(''.join(sorted(s, reverse=True)))
n2 = int(''.join(sorted(s)))
if n1 == n2:
    print('%04d - %04d = 0000' % (n1, n2))
else:
    while 1:
        r = n1 - n2
        print('%04d - %04d = %04d' % (n1, n2, r))
        if r == 6174:
            break
        s = str(r)
        if len(s) < 4:
            s += '0' * (4-len(s))
        n1 = int(''.join(sorted(s, reverse=True)))
        n2 = int(''.join(sorted(s)))

运行结果

测试点结果耗时内存
0答案正确24 ms3100KB
1答案正确23 ms3076KB
2答案正确23 ms3056KB
3答案正确24 ms3056KB
4答案正确24 ms3284KB
5答案正确25 ms3412KB
6答案正确24 ms3180KB

1020 月饼

月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。

注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18、15、10万吨,总售价分别为75、72、45亿元。如果市场的最大需求量只有20万吨,那么我们最大收益策略应该是卖出全部15万吨第2种月饼、以及5万吨第3种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入格式:

每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数、以及不超过500(以万吨为单位)的正整数D表示市场最大需求量。随后一行给出N个正数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。

输出格式:

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后2位。

输入样例:

3 20
18 15 10
75 72 45

输出样例:

94.50

思路及注意点

  1. 每种月饼保存成一个元组,包含月饼的库存、总售价和单价。根据单价从小到大排序,优先选择排序后的序列中靠后的元组,因此可以使用列表的pop方法。
  2. 注意月饼的库存量和总售价题目中只说是正数,不一定是正整数,因此要用float。
  3. 注意所有月饼的库存仍不满足需求的情况。

代码

s = input().split()
n = int(s[0])
d = int(s[1])
l = [()] * n
c = list(map(float, input().split()))
p = list(map(float, input().split()))
for i in range(n):
    l[i] = (c[i], p[i], p[i]/c[i])
l.sort(key=lambda x: x[2])
num = 0
price = 0
while num < d:
    item = l.pop()
    if num + item[0] <= d:
        num += item[0]
        price += item[1]
    else:
        price += item[2] * (d-num)
        num = d
    if not l:
        break
print('%.2f' % price)

运行结果

测试点结果耗时内存
0答案正确34 ms3156KB
1答案正确27 ms3296KB
2答案正确23 ms3056KB
3答案正确24 ms3376KB
4答案正确26 ms3472KB
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值