先給程式碼:
print(*[f'Case {i+1}: {(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))}' for i in range(int(input()))], sep='\n')
區間開始(大於a的最小奇數)a+(a+1)%2
區間結束(小於b的最大奇數)b-(b+1)%2
題目更新為[a+(a+1)%2, b-(b+1)%2
]之間的所有奇數和
※注意到當a==b且兩數皆為偶數時,如a=4, b=4時,a與b的值會變為5及3,a>b,此例外要留意
帶入公式可得 得出所求=(a+(a+1)%2 + b-(b+1)%2) * (b-(b+1)%2 - a-(a+1)%2) / 2
由於a, b在公式中會使用到多於一次,所以我們不能用單純int(input())
來取代a及b
所以我們就要使用非常強大的lambda匿名函式了
用法:lambda arguments : expression
(基本上)相當於
def foo(arguements):
return expression
用法(大致上)分為三種:
直接呼叫:如 print((lambda x: x**2+x+1)(int(input())))
#輸出int(input())代入f(x)=x^2+x+1的值
一行宣告函式:如 sqrt = lambda x: round(r**0.5, 2) #程式碼即可呼叫sqrt(x)如一般函式一樣
內建函式(map(),sorted()等)的參數:例如以每一row的第二項排序二維陣列可使用sorted([[1, 2], [4, 1], [3, 1], [0, 3]], key=lambda l: l[1]) #[[3, 1], [4, 1], [1, 2], [0, 3]]
這題中我們可以這樣寫...
還記得前面說的例外嗎? 這個例外只會發生在a==b且a%2==b%2==0時,因為我們在寫的是expression而不是statement所以我們可以在同一行使用if..else...迴圈,其 syntax 為
expression if a else b
若是搭配loop comprehension: (題外話)
expression for i in list if a
expression if a else b for i in list
所以我們可以寫:
(lambda a, b: (前面推導出的公式) if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))
(後面的參數要代入兩個input)
於是我們就有single case的程式碼了
如何寫成多組測資?
兩種寫法:A(將所有答案儲存在一個list中最後一起輸出) B(每計算完一組答案就輸出一次)
要一行解的話我們所有的for迴圈都要使用list comprehension,而其中不能寫statement只能寫expression,所以我們只能選擇A方案
list comprehension,簡單來說就是把
temp = []
for i in list:
temp.append(i)
寫為
temp = [i for i in list]
於是我們的程式碼就成為了
print([(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input())) for i in range(int(input()))])
有一件事情很重要:我們可以這麼寫的原因是因為程式碼執行時會先讀到range()中的input()而不是lambda函式中的input(),如同一般for迴圈一樣
記得加[]或是在其他情況之下,加上你想要的資料型態,否則傳回的是一個generator object而不是list或其他資料型態
最後會輸出[9, 8]
但是我們想要的是Case #1....的輸出方式
所以我們就可以使用f-string了:)
這裡就不多介紹f-string了,篇幅真的太長了QQ
print([f'Case {i+1}: {(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))}' for i in range(int(input()))])
輸出['Case 1: 9', 'Case 2: 8']
最後我們有三種方式來完成此題
A) 使用starred expression搭配print()中的sep參數
print(*[f'Case {i+1}: {(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))}' for i in range(int(input()))], sep='\n')
B) 使用.join()方法
print('\n'.join([f'Case {i+1}: {(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))}' for i in range(int(input()))]))
C) 使用starred expression並修改f-string再搭配print()中的sep, end參數(千千萬萬拜託不要用這個
print(*[f'Case {i+1}: {(lambda a, b: (b-(b+1)%2 + a+(a+1)%2)*((b-(b+1)%2 - a-(a+1)%2)//2+1)//2 if b>a or b%2==a%2==1 else 0)(int(input()), int(input()))}\n' for i in range(int(input()))], sep='', end='')
這樣就可以AC了,希望有看到這裡的各位有學到一些東西:)
ps打這個報告花我超久...