CCF — 碰撞的小球(Python實現:100分)
2018.03.2 碰撞的小球
目錄
前言
最近我在做CCF的題目,也打算把每道題的解題思路都寫到部落格上來,希望能幫助到也在做CCF題目的讀者們,希望你們通過本文能有所提示,幫助大家提升程式設計能力。另外有個很好的想法就是,建議讀者們可以先看一下問題分析的部分,然後自己再整理一下思路,重新做一遍,最後再參考程式碼,我想這樣會更有收穫。
一、問題描述
問題描述
數軸上有一條長度為L(L為偶數)的線段,左端點在原點,右端點在座標L處。有n個不計體積的小球線上段上,開始時所有的小球都處在偶數座標上,速度方向向右,速度大小為1單位長度每秒。
當小球到達線段的端點(左端點或右端點)的時候,會立即向相反的方向移動,速度大小仍然為原來大小。
當兩個小球撞到一起的時候,兩個小球會分別向與自己原來移動的方向相反的方向,以原來的速度大小繼續移動。
現在,告訴你線段的長度L,小球數量n,以及n個小球的初始位置,請你計算t秒之後,各個小球的位置。
提示
因為所有小球的初始位置都為偶數,而且線段的長度為偶數,可以證明,不會有三個小球同時相撞,小球到達線段端點以及小球之間的碰撞時刻均為整數。
同時也可以證明兩個小球發生碰撞的位置一定是整數(但不一定是偶數)。
輸入格式
輸入的第一行包含三個整數n, L, t,用空格分隔,分別表示小球的個數、線段長度和你需要計算t秒之後小球的位置。
第二行包含n個整數a1, a2, …, an,用空格分隔,表示初始時刻n個小球的位置。
輸出格式
輸出一行包含n個整數,用空格分隔,第i個整數代表初始時刻位於ai的小球,在t秒之後的位置。
樣例輸入
3 10 5
4 6 8
樣例輸出
7 9 9
樣例說明
初始時,三個小球的位置分別為4, 6, 8。
一秒後,三個小球的位置分別為5, 7, 9。
兩秒後,第三個小球碰到牆壁,速度反向,三個小球位置分別為6, 8, 10。
三秒後,第二個小球與第三個小球在位置9發生碰撞,速度反向(注意碰撞位置不一定為偶數),三個小球位置分別為7, 9, 9。
四秒後,第一個小球與第二個小球在位置8發生碰撞,速度反向,第三個小球碰到牆壁,速度反向,三個小球位置分別為8, 8, 10。
五秒後,三個小球的位置分別為7, 9, 9。
樣例輸入
10 22 30
14 12 16 6 10 2 8 20 18 4
樣例輸出
6 6 8 2 4 0 4 12 10 2
資料規模和約定
對於所有評測用例,1 ≤ n ≤ 100,1 ≤ t ≤ 100,2 ≤ L ≤ 1000,0 < ai < L。L為偶數。
保證所有小球的初始位置互不相同且均為偶數。
二、問題分析
本題的主要解題思路如下:
①將整個大問題分成幾個小問題,分別有三種情況:球與球碰撞、球與牆碰撞、球每秒運動一個單位
②球與球碰撞情況:利用兩層迴圈,遍歷每顆球與其他球是否碰撞,若碰撞則判斷當前球的方向,使其改變運動方向;
③球與牆碰撞情況:遍歷每顆球,判斷當前的單位值是否大於線段長度或小於0,則相應的改變運動方向
④球每秒運動一個單位:遍歷每顆球,根據運動方向對應的增加一個單位或減少一個單位。
⑤先改變方向再運動,所以先呼叫兩個改變方向的方法,再呼叫球運動的方法,最後輸出運動結果即可。
三、程式說明
n:輸入n個小球
L:線段的長度
t:運動 t 秒
p:用於儲存n個小球的列表
isRL:儲存n個小球的運動方向(R:向右運動;L:向左運動)
Python語言的程式如下:
# 碰撞的小球
# 球與球碰撞,改變方向
def bumpBall(p,isRL):
for i in range(0,len(p)):
for j in range(i+1,len(p)):
if p[i] == p[j]:
if isLR[i] == 'R':
isLR[i] = 'L'
isRL[j] = 'R'
else:
isLR[i] = 'R'
isRL[j] = 'L'
# 球撞牆,改變方向
def bumpWall(p,isRL,L):
for i in range(0,len(p)):
if p[i] == L:
isRL[i] = 'L'
elif p[i] == 0:
isRL[i] = 'R'
# 移動小球
def moveBall(p,isRL):
for i in range(0,len(p)):
if isRL[i] == 'R':
p[i] += 1
elif isRL[i] == 'L':
p[i] -= 1
s = input().split()
s1 = input().split()
n = int(s[0])
L = int(s[1])
t = int(s[2])
p = []
isLR = []
for i in range(0,n):
p.append(int(s1[i]))
isLR.append('R') # 初始向右
for i in range(1,t+1):
bumpBall(p,isLR)
bumpWall(p,isLR,L)
moveBall(p,isLR)
for i in p:
print('%d ' %i, end='')