CCF-CSP ISBN號碼
問題描述
試題編號:201312-2 試題名稱:ISBN號碼 時間限制:1.0s 記憶體限制:256.0MB 問題描述 每一本正式出版的圖書都有一個ISBN號碼與之對應,ISBN碼包括9位數字、1位識別碼和3位分隔符,其規定格式如“x-xxx-xxxxx-x”,其中符號“-”是分隔符(鍵盤上的減號),最後一位是識別碼,例如0-670-82162-4就是一個標準的ISBN碼。ISBN碼的首位數字表示書籍的出版語言,例如0代表英語;第一個分隔符“-”之後的三位數字代表出版社,例如670代表維京出版社;第二個分隔之後的五位數字代表該書在出版社的編號;最後一位為識別碼。 識別碼的計算方法如下: 首位數字乘以1加上次位數字乘以2……以此類推,用所得的結果mod 11,所得的餘數即為識別碼,如果餘數為10,則識別碼為大寫字母X。例如ISBN號碼0-670-82162-4中的識別碼4是這樣得到的:對067082162這9個數字,從左至右,分別乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然後取158 mod 11的結果4作為識別碼。 編寫程式判斷輸入的ISBN號碼中識別碼是否正確,如果正確,則僅輸出“Right”;如果錯誤,則輸出是正確的ISBN號碼。 輸入格式 輸入只有一行,是一個字元序列,表示一本書的ISBN號碼(保證輸入符合ISBN號碼的格式要求)。 輸出格式 輸出一行,假如輸入的ISBN號碼的識別碼正確,那麼輸出“Right”,否則,按照規定的格式,輸出正確的ISBN號碼(包括分隔符“-”)。 樣例輸入 0-670-82162-4 樣例輸出 Right 樣例輸入 0-670-82162-0 樣例輸出 0-670-82162-4
題解1
這個題思路很簡單,只要按照題目所給出的識別碼的計算方法進行計算得出即可。但是,要注意,mod 11,所得的餘數即為識別碼,如果餘數為10,則識別碼為大寫字母X。特別要處理餘數為10的情況。
s = input() a = list(map(int, s[0:len(s) - 1].replace('-', '')))# 處理輸入 sum = 0 for i in range(1, 10): sum = sum + i * a[i - 1]# 求和 m = sum % 11 if (str(m) == s[-1]) or (m == 10 and s[-1] == "X"):# 識別碼正確,輸出Right print("Right") elif m == 10 and s[-1] != "X":# 處理餘數為10且最後一位不為X的情況 s = s[0:len(s) - 1] + "X" print(s) else:# 輸出正確的識別碼 s = s[0:len(s) - 1] + str(m) print(s)
題解2
由於題目結題思路比較簡單,所以題解2與題解1沒有本質區別,只是程式寫法上有一些細節上的區別。
s = input() b = "".join(s.split('-'))# 處理輸入 c = int() count = 0 while count < 9: c += int(b[count]) * (count + 1) count += 1 d = c % 11 if d == 10:# 處理餘數為10的情況 if b[9] == 'X': print('Right')# 識別碼正確,輸出Right else: print(s[0:12] + 'X')# 輸出正確的識別碼 else: if str(d) == b[9]: print('Right')# 識別碼正確,輸出Right else: print(s[0:12] + str(d))# 輸出正確的識別碼
知識點補充
字串切片
切片操作可以從一個字串中獲取子字串,語法格式為:
[start:end:step]
-
[:]
提取從開頭(預設位置0)到結尾(預設位置-1)的整個字串 -
[start:]
從start
提取到結尾 -
[:end]
從開頭提取到end - 1
-
[start:end]
從start
提取到end - 1
-
[start:end:step]
從start
提取到end - 1
,每step
個字元提取一個 -
左側第一個字元的位置/偏移量為
0
,右側最後一個字元的位置/偏移量為-1
>>>s = "abcdefgh" >>>s[0:2]# 前兩個字元 'ab' >>>s[0:]# 整個字串 'abcdefgh' >>>s[:]# 整個字串 'abcdefgh' >>>s[:-1]# 去除字串最後一個字元 'abcdefg' >>>s[-2:]# 倒數兩個字元 'gh' >>>s[::2]# 步長為2 'aceg'
字串替換
- 切片實現替換
最簡單的辦法是通過字串切片與連線操作來實現字串替換:
>>>s = 'abcd' >>>s[:2] + 'ef'# 替換後兩個字元 'abef'
- replace() 方法
replace()
方法把字串中的 舊字串替換成新字串,如果指定第三個引數max
,則替換不超過max
次。語法格式:
str.replace(old, new[, max])
引數說明:
-
old
將被替換的子字串。 -
new
用於替換old
子字串的新字串。 -
max
可選引數, 替換不超過max
次。
返回值:
返回字串中的old
(舊字串) 替換成new
(新字串)後生成的新字串,如果指定第三個引數max
,則替換不超過max
次。
使用示例:
>>>s = "a-b-c-d" >>>s.replace('-', '') 'abcd' >>>s.replace('-', '', 2)# 指定只替換兩次 'abc-d'
- 正則表示式
使用正則表示式模組也可以實現替換。
re.sub(pattern, repl, string, count)
引數說明:
pattern repl string count
使用示例:
import re s = "Hello World!" print(re.sub('[A-Z]', '*', s))# 將s中的大寫字母替換為*號
輸出結果:
*ello *orld!
- 替換指定位置的字元**
將字串轉換成列表後修改值,然後用join()
方法組成新字串。替換單個位置的字元:
def replace_by_index(string, index, c): new = [] for i in string: new.append(i) new[index] = c return ''.join(new) # 將索引為2的字元替換為f res = replace_by_index("abcd", 2, 'f') print(res)
輸出結果:
abfd
替換字串中多個指定位置為指定字元:
# 替換字串中多個指定位置的字元 # pos:位置列表,chr:對應替換的字元列表 def multi_replace_by_index(s, pos, chr): new = [] for i in s: new.append(i) for index in pos: new[index] = chr[index-1] return ''.join(new) res = multi_replace_by_index("abcd", [1, 2], ['f', 'm']) print(res)
輸出結果:
afmd
字串拼接
- +號
使用加號可以直接連線兩個字串,返回新的字串。
>>>s1 = "ab" >>>s2 = "cd" >>>s1 + s2 'abcd'
- join() 方法
join()
方法用於將序列中的元素以指定的字元連線生成一個新的字串。
str.join(sequence)
引數說明:sequence
– 要連線的元素序列。sequence
中的元素必須是字元或字串,否則會報錯。
返回值:返回通過指定字元連線序列中元素後生成的新字串。
使用示例:
>>>s1 = "-" >>>seq = ['a', 'b', 'c', 'd']#連線的序列是列表 >>>s1.join(seq) 'a-b-c-d' >>>seq = ('a', 'b', 'c', 'd')#連線的序列是元組 >>>s1.join(seq) 'e-f-g-h' >>>seq = "ijkl"#連線的序列是字串 >>>s1.join(seq) 'i-j-k-l' >>>seq = {"m":1, "n":2, "o":3, "p":4}#連線的序列是字典,會將所有key連線起來 >>>s1.join(seq) 'm-n-o-p' >>>s1 = "---"#使用多字元連線序列 >>>seq = "abcd" >>>s1.join(seq) 'a---b---c---d'
- format() 方法
str.format()
為格式化字串的函式。基本語法是通過 {} 和 : 來代替以前的 % 。format()
函式可以接受不限個引數,位置可以不按順序。
>>>a = "I" >>>b = "Love" >>>c = "You" >>>'{} {} {}'.format(a, b, c)# 按預設順序 'I Love You' >>>'{2} {1} {0}'.format(a, b, c)# 指定位置 'You Love I' >>>'{0} {1[0]} {1[1]}'.format(a, [b, c])# 傳入引數為列表 'I Love You'