一、原題
問題描述
| 試題編號: |
201712-2 |
| 試題名稱: |
游戲 |
| 時間限制: |
1.0s |
| 內存限制: |
256.0MB |
| 問題描述: |
問題描述 有n個小朋友圍成一圈玩游戲,小朋友從1至n編號,2號小朋友坐在1號小朋友的順時針方向,3號小朋友坐在2號小朋友的順時針方向,……,1號小朋友坐在n號小朋友的順時針方向。 輸入格式 輸入一行,包括兩個整數n和k,意義如題目所述。 輸出格式 輸出一行,包含一個整數,表示獲勝的小朋友編號。 樣例輸入 5 2 樣例輸出 3 樣例輸入 7 3 樣例輸出 4 數據規模和約定 對於所有評測用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。 |
二、題解
用到兩個列表和一個計數器。計數器用來記錄當前小朋友的報數。第一個列表用來裝沒有報數的小孩。第二個列表用來裝報數並且不是k的整數倍的小孩。當第一個列表循環完一遍以后,把第二個列表重新復制給第一個列表。然后第二個列表置空。然后循環第二遍。當第一個列表長度是1時停止循環。然后輸出當前小孩的序號。
注意:
- 用range生成時,Python3是生成一個迭代器。所以需要用list來實際在內存生成這個列表。然后是這個列表的每個元素對應的小孩應該是這個數字加1(或者range生成列表從1開始到n+1)才是小孩的真正序號。
- 題中有兩點兒要求:一是小朋友數到k時淘汰;二是小朋友報數的個位數為k時小朋友也被淘汰。
三、代碼
- 以下提交20分:
L = list(map(int,input().split()))
n, k = L[0], L[1]
li = list(range(n))
c = 1
while len(li) > 1:
li1 = []
for i in range(len(li)):
if c%k==0:
c += 1
else:
li1.append(li[i])
c += 1
li = li1[:]
print(li[0]+1)
- 修改后提交得30分:
L = list(input().split())
n, k = int(L[0]), int(L[1])
li = list(range(1,n+1))
c = 1
while len(li) > 1:
li1 = []
#之前沒有考慮到k=1
if k == 1:
li1.append(li[-1])
li = li1[:]
break
for i in range(len(li)):
if c%k==0:
c += 1
else:
li1.append(li[i])
c += 1
li = li1[:]
print(li[0])
- 認真審題以后發現還有報數的個位數為K時也會淘汰。所以更改如下:
L = list(input().split())
n, k = int(L[0]), int(L[1])
li = list(range(1,n+1))
c = 1
while len(li) > 1:
li1 = []
#之前沒有考慮到k=1
if k == 1:
li1.append(li[-1])
li = li1[:]
break
for i in range(len(li)):
#之前沒有考慮個位數為k
if (c%k==0) or (c%10==k):
c += 1
else:
li1.append(li[i])
c += 1
li = li1[:]
print(li[0])
