天天看點

csp_碰撞的小球

題目連結

csp_碰撞的小球
csp_碰撞的小球
csp_碰撞的小球
csp_碰撞的小球

使用一個結構體存儲小球的位置和運動方向,每過1s就改變每個小球的位置,這可以通過一層for解決,如果到達邊界就方向反向,(分析出不會有倆小球同時到邊界),接着用雙重for檢查每個小球是否存在和它位置相同的小球,(不會同時有3小球碰撞,同一位置更不會有四個小球,是以在同一位置肯定隻有一對球),改變這一對球的方向,這裡有一個問題是不加處理的話,A會找到B同位置然後方向互換,B會找到A同位置然後方向互換,導緻相當于沒變更方向,解決方法是對每個坐标位置記錄在這裡碰撞的次數,初值是0,有小球在此位置碰撞就自增1,如果是奇數,表示第一次碰撞,讓兩球方向互換,如果偶數則不變方向。也可以用個bool類型輔助判斷。

處理麻煩了,找同一位置j不需要從頭開始找,從j+1就可:

//對每個球檢查位置相同的,改變方向
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(balls[i].pos == balls[j].pos){
                    //奇數是第一次改變
                    balls[i].dir=!balls[i].dir;
                    balls[j].dir=!balls[j].dir;
                }
            }
        }
           

代碼:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

struct Ball{
    int pos;
    bool dir;//true為向右 false為向左
}balls[101];
int position[1001]={0};//奇數表示第一次處理碰撞情形,偶數表示第二次處理碰撞情形

int main()
{
    int n,L,t;
    cin >> n >> L >> t;
    for(int i=0;i<n;i++){
        cin >> balls[i].pos;
        balls[i].dir=true;//開始都是向右走
    }
    while(t--){
        //每一秒先依據位置和方向改變位置
        for(int i=0;i<n;i++){
            if(balls[i].dir==true) balls[i].pos++;
            else balls[i].pos--;
            if(balls[i].pos==0 || balls[i].pos==L)
                balls[i].dir=!balls[i].dir;//到邊界改變位置
        }
        //對每個球檢查位置相同的,改變方向
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){//處理麻煩了,其實j從i+1周遊就行
                if(i!=j && balls[i].pos == balls[j].pos){
                    position[balls[i].pos]++;
                    if(position[balls[i].pos] &1){
                        //奇數是第一次改變
                        balls[i].dir=!balls[i].dir;
                        balls[j].dir=!balls[j].dir;
                    }
                }
            }
        }
    }
    for(int i=0;i<n;i++){
        cout << balls[i].pos << " ";
    }
    return 0;
}

           

繼續閱讀