OJ上的三道Python題
昨天在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))
這題總算過了。