欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

OJ上的三道Python题

程序员文章站 2022-06-05 20:17:06
昨天在OJ上做了19级理科大计基的12道题,有两个始终过不去,今天写了最后一道,过了。把这三道题分享一下。超市收银系统时间限制: 1000 ms 内存限制: 65536 kb题目题目描述本题描述有更改,清注意一般超市或商店的收银台在对商品扫码之后会得到一串数字,这串数字代表一种商品。假设已知所有商品的名称、代码和单价,现在需要你写一个程序,输入扫码得到的商品代码(假设固定为6位数字),计算所购买的每种商品的数量(件数)、总价,并按照字典序打印商品的小票(如果某种商品购买了多件,应在同一行内输出...

昨天在OJ上做了19级理科大计基的12道题,有两个始终过不去,今天写了最后一道,过了。

把这三道题分享一下。

超市收银系统

时间限制: 1000 ms 内存限制: 65536 kb

题目

题目描述

本题描述有更改,清注意

一般超市或商店的收银台在对商品扫码之后会得到一串数字,这串数字代表一种商品。假设已知所有商品的名称、代码和单价,现在需要你写一个程序,输入扫码得到的商品代码(假设固定为6位数字),计算所购买的每种商品的数量(件数)、总价,并按照字典序打印商品的小票(如果某种商品购买了多件,应在同一行内输出该商品的名称数量单价总价)。计算所购买所有商品的总金额,并打印。 给出商品目录如下:

格式:名称 代码 单价
chips 932071 3.50
chocolate 114049 8.00
soap 304985 2.90
cupcake 955962 4.90
cookie 313903 6.50
milk 243813 3.20
toothbrush 961995 4.80
toothpaste 933328 9.30
teapot 914500 29.80

输入

每行为一个6位数字,代表所购买的商品代码。当所有购买商品输入完毕时,以输入0为结束输入标志。(毕竟你不可能跟收银员说我买了n件商品嘛)。

输出

一张小票,要求: 第一行包含“NAME”、“QUANTITY”、“PRICE”、“SUM”(代表商品的名称、数量、单价和总价),各单词之间用若干空格分隔。

接下来若干行,每行对应所购买的某种商品的明细。要求每列按照该项目内容字符数量最多的那一项填充空格补齐(第一行也要补齐),要求每列左对齐,对齐之后项目之间还要空一格。

总价输出保留两位小数,其余数字按照Python默认输出。

按照商品名称的字典序输出。提示:可使用list.sort()

最后一行是所购买所有商品的总金额,格式为:total:xxx.xx(注意:这里是西文的冒号,保留小数点后2位)

输入样例

932071
114049
932071
932071
114049
114049
932071
0

输出样例

NAME      QUANTITY PRICE SUM
chips     4        3.5   14.00
chocolate 3        8.0   24.00
total:38.00

解答

由于商品信息已经给出,所以就直接手动排好序存在list里。

扫描商品时录入的是代码,为了方便查询,这里使用了dict,以商品代码作为key,在list中的索引为value,便于直接查找。每扫描一个就增加对应商品的数量。

最后输出时需要对齐,而商品不确定,所以需要先找到最长的商品名,然后对齐输出。

代码如下:

# 商品信息:商品名,单价,数量
list = [["chips", 3.50, 0], ["chocolate", 8.00, 0], ["cookie", 6.50, 0], ["cupcake", 4.90, 0], [
    "milk", 3.20, 0], ["soap", 2.90, 0], ["teapot", 29.80, 0], ["toothbrush", 4.80, 0], ["toothpaste", 9.30, 0]]
# 商品代码及对应序号
dic = {"932071": 0, "114049": 1, "313903": 2, "955962": 3,
       "243813": 4, "304985": 5, "914500": 6, "961995": 7, "933328": 8}
# 第一列长度的最大值
maxlen = 4
while True:
    x = input()
    if x == "0":
        break
    # 商品数量加1
    list[dic[x]][2] += 1
    if(len(list[dic[x]][0]) > maxlen):
        maxlen = len(list[dic[x]][0])
# 第一列与第二列间有空格
maxlen += 1
total = 0
# 第一列
print("NAME"+" "*(maxlen-4)+"QUANTITY PRICE SUM")
for i in list:
    # 输出数量不为0的商品
    if i[2] != 0:
        sum = i[2]*i[1]
        total += sum
        print(i[0]+" "*(maxlen-len(i[0]))+"%-9d%-6.1f%.2f" % (i[2], i[1], sum))
print("total:%.2f" % total)

输出和样例一样,却一直报WA,也看不到题解,不知道为啥。

代码对齐

时间限制: 1000 ms 内存限制: 65536 kb

题目

题目描述

Python代码要求严格对齐才能执行。但是对齐问题往往很难发现,有时候只是某一行少了或者多了一个空格,就会报错。现在请你编写一个Python程序来帮你整理一下代码,解决少空格或多空格的问题。

要求:

(1)把所有的tab('\t')换成4个空格。

(2)使每一行前的空格数必须是4的倍数。把空格补充成不小于自身的最小的4的倍数。如,3个空格补成4个,5个空格补成8个。

注意:这样的要求并不能保证输出代码一定是语法正确的。

(3)确保“#”与注释文字间至少有一个空格。只需要处理每行的第一个“#”即可,将后面的“#”看做注释中的文字。

输入

第一行是一个正整数n,代表代码的行数。

接下来n行,是需要整理的代码。

输出

整理后的代码。

输入样例

8
#terrible code
for i in range(100):
   if i % 2 == 0:
       print('%d is an even number\n'%i)
  if i % 3 == 0:
     print('%d can be divided by 3\n'%i)
#tell people it's over
print('It\'s over')

输出样例

# terrible code 
for i in range(100):
    if i % 2 == 0:
        print('%d is an even number\n'%i)
    if i % 3 == 0:
        print('%d can be divided by 3\n'%i)
# tell people it's over
print('It\'s over')

解答

先处理tab,利用str.expandtabs()函数将所有tab替换为4个空格。

然后补全空格,先算出行首空格数,然后用str.lstrip()去掉空格再添加空格。

最后补全#后的空格,遍历搜索。

代码如下:

import math
n = int(input())
for j in range(n):
    line = input()
    length = len(line)
    # 替换tab后去掉开头空格
    line = line.expandtabs(4).lstrip()
    # 补全空格
    line = " "*math.ceil((length-len(line))/4)*4+line
    lis = list(line)
    # 补上第一个#后的空格
    for i in range(len(lis)):
        if(lis[i] == '#' and i+1 < len(lis) and lis[i+1] != ' '):
            lis.insert(i+1, ' ')
    print("".join(lis))

输出和样例一样,一直报PE。

转圈圈

时间限制: 1000 ms 内存限制: 65536 kb

题目

题目描述

情人节到了(其实是过去了),偷偷送大家一道题。

本题要求你输出一个尺寸为d×d的数阵,数字的排列方式是从1到n循环且顺时针转圈,看样例输出。

输入

两行,第一行是正整数n(n<10),第二行是正整数d(d<20)

输出

转圈圈的数阵

输入样例1

6
4

输出样例1

1 2 3 4
6 1 2 5
5 4 3 6
4 3 2 1

输入样例2

5
5

输出样例2

1 2 3 4 5
1 2 3 4 1
5 4 5 5 2
4 3 2 1 3
3 2 1 5 4

解答

想法比较简单,设置一个变量用于控制填充方向,到达拐点后改变方向。

代码如下:

n = int(input())
d = int(input())
# d*d列表
a = [[0]*d for i in range(d)]
# 填充方向
direct = 0
# 当前填充坐标
x = 0
y = 0
for i in range(d*d):
    a[x][y] = i % n+1
    if direct == 0:
        if y+1 < d and a[x][y+1] == 0:
            y += 1
        else:
            x += 1
            direct = 1
    elif direct == 1:
        if x+1 < d and a[x+1][y] == 0:
            x += 1
        else:
            y -= 1
            direct = 2
    elif direct == 2:
        if a[x][y-1] == 0:
            y -= 1
        else:
            x -= 1
            direct = 3
    else:
        if a[x-1][y] == 0:
            x -= 1
        else:
            y += 1
            direct = 0
for i in a:
    s = [str(j) for j in i]
    print(" ".join(s))

这题总算过了。

本文地址:https://blog.csdn.net/MeanCoder/article/details/107369992