CCF2018年3月第2題(碰撞的小球)Java解法
阿新 • • 發佈:2019-02-11
題目描述:數軸上有長度為L(L為偶數)的線段,左端點0,右端點L。n個小球開始都是向右,且都在偶數座標上,速度大小為1單位長度每秒。
當小球到達端點(0或L)時,立即反向,速度不變;當兩個小球相撞(在同一位置),立即反向,速度不變。
現在告訴你線段長度L,小球數量n,以及n個小球初始位置,請計算t秒之後各個小球的位置。
提示:同一時刻同一位置最多隻有兩個小球相撞,由於速度始終不變,所以碰撞時間也是整數,且在碰撞的位置也是整數(但不一定只能是偶數)。
輸入格式:第一行包括n(球的個數),L(線段長度),t(t秒之後),空格分隔。
第二行包括n個整數a1,a2...an。分別代表球1到球n在初始時刻的位置。
輸出格式:包含n個整數,空格分隔,第i個整數代表球i在t時刻的位置。
樣例輸入:
3 10 5
4 6 8
樣例輸出:
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 < ai < L
解題思路:
建立小球物件Ball,在小球物件中設定要用的方法:小球方向的改變,碰到牆的情況,定義小球的初始方向,以及小球的座標點;
之後在主方法中只需要判斷小球往右時+1,往左時-1,碰到牆和兩球相撞時方向改變,時間消耗完就得到了所有小球的座標;
程式碼:
import java.util.Scanner;
//建立小球物件
class Ball{
//設定為true表示方向向右
boolean side = true;
//定義小球的座標
int point = 0;
//方向的改變
public void changeSide() {
if(this.side) {
this.side = false;
}else {
this.side = true;
}
}
//碰到牆的情況,L表示整個座標軸長度
public void pWall(int L) {
if(this.point == L || this.point == 0)
changeSide();
}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int L = scanner.nextInt();
int t = scanner.nextInt();
Ball[] balls = new Ball[n];
int i;
//獲取初始座標
for(i = 0; i < n; i++) {
balls[i] = new Ball();
balls[i].point = scanner.nextInt();
}
//一開始就要運動了1s,所以用--t
while(--t > -1) {
//小球向右運動+1,向左運動-1
for(i = 0; i < n; i++) {
if(balls[i].side)
balls[i].point++;
else
balls[i].point--;
//運動一秒後判斷是否碰到牆了
balls[i].pWall(L);
}
//兩球相碰時方向都改變
for(i = 0; i < n-1; i++) {
for(int j = i + 1; j < n; j++) {
if(balls[i].point == balls[j].point) {
balls[i].changeSide();
balls[j].changeSide();
}
}
}
}
//輸出最後的座標
for(i = 0; i < n; i++) {
if(i == n-1)
System.out.print(balls[i].point);
else
System.out.print(balls[i].point + " ");
}
}
}
最後在CCF上提交的結果是100分!!!