1. 程式人生 > >CCF2018年3月第2題(碰撞的小球)Java解法

CCF2018年3月第2題(碰撞的小球)Java解法

題目描述:數軸上有長度為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分!!!