1. 程式人生 > >CCF201803-2 碰撞的小球

CCF201803-2 碰撞的小球

試題編號: 201803-2
試題名稱: 碰撞的小球
時間限制: 1.0s
記憶體限制: 256.0MB
問題描述:

問題描述

  數軸上有一條長度為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。
RequireFile.do?fid=b6beJN6e
  一秒後,三個小球的位置分別為5, 7, 9。
RequireFile.do?fid=Ab8QmfeR
  兩秒後,第三個小球碰到牆壁,速度反向,三個小球位置分別為6, 8, 10。
RequireFile.do?fid=fgQLYbNn
  三秒後,第二個小球與第三個小球在位置9發生碰撞,速度反向(注意碰撞位置不一定為偶數),三個小球位置分別為7, 9, 9。
RequireFile.do?fid=erfyNJDT
  四秒後,第一個小球與第二個小球在位置8發生碰撞,速度反向,第三個小球碰到牆壁,速度反向,三個小球位置分別為8, 8, 10。
RequireFile.do?fid=m5EBf6q8
  五秒後,三個小球的位置分別為7, 9, 9。
RequireFile.do?fid=JRHaHt4T

樣例輸入

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為偶數。
  保證所有小球的初始位置互不相同且均為偶數。

C++ 程式如下

#include<iostream> 
using namespace std;

int main()
{
      int n, l , t ;
       cin >> n >> l >> t;
       int pos[n];
       int spe[n];
       for ( int  i=0; i<n;i++)
        {
	       cin >> pos[i];
          spe[i] = 1 ;
         // 如果恰好在右端點 則 速度相反 
         if(pos[i] == l )

            spe[i] = -spe[i];
          }

 
        while(t--)
     {
        
        for(int i =0; i<n ; i++)
      
        {
          pos[i] += spe[i];

         if(pos[i]== l || pos[i] == 0)
          spe[i]= -spe[i];  
         }
     
         for(int j = 0; j < n; j++)

            for(int k = j + 1; k < n; k++)
          
	     if(pos[k] == pos[j])

                    spe[k] = -spe[k], spe[j] = -spe[j];
             
        
     }
        for ( int  i=0; i<n;i++)
        {
	       cout  << pos[i]<< " ";
       
         }
        cout<< endl;
  return 0 ; 
}

    思路總結:

   1、 第一次嘗試 第二題  開始真的是被題嚇住了,  看了好多 題解   又是模擬 又是排序 啥的  很暈   

          以為還要涉及 沒有看過的演算法  但靜下心發現  其實也不難     相比而言就是過程多了  思考的要多了

        提示比較重要   ac後整體看來不算難題

  2、  吸收到一句話  沒有好方法就暴力 沒有好方法就模擬。

  3、  提交了好幾次  每次都發現有這樣那樣的問題, 認證大賽是黑盒測試  根本不出成績  需要有絕對的嚴謹。

  4、  看到一些無法理解的 程式   大概是傳說的  程式設計規範吧   現在看來影響不大  而且確實理解不了  先打基礎吧

  5 、  整個過程沒有什麼特別的   就是模擬  就是  推演一邊過程   細化分步 一步一步來    最後考慮特殊情況

          隨著程式碼數增多   養成程式設計過程中就寫註釋的習慣。