試題編號: | 201803-2 |
試題名稱: | 碰撞的小球 |
時間限制: | 1.0s |
內存限制: | 256.0MB |
問題描述: | 問題描述 數軸上有一條長度為L(L為偶數)的線段,左端點在原點,右端點在坐標L處。有n個不計體積的小球在線段上,開始時所有的小球都處在偶數坐標上,速度方向向右,速度大小為1單位長度每秒。 提示 碰撞球游戲、 因為所有小球的初始位置都為偶數,而且線段的長度為偶數,可以證明,不會有三個小球同時相撞,小球到達線段端點以及小球之間的碰撞時刻均為整數。 輸入格式 輸入的第一行包含三個整數n, L, t,用空格分隔,分別表示小球的個數、線段長度和你需要計算t秒之后小球的位置。 輸出格式 碰撞大賽一、 輸出一行包含n個整數,用空格分隔,第i個整數代表初始時刻位于ai的小球,在t秒之后的位置。 樣例輸入 3 10 5 樣例輸出 ccf2020答案?7 9 9 樣例說明 初始時,三個小球的位置分別為4, 6, 8。 樣例輸入 ccf第三題、10 22 30 樣例輸出 6 6 8 2 4 0 4 12 10 2 數據規模和約定 ccf2021初賽、 對于所有評測用例,1 ≤ n ≤ 100,1 ≤ t ≤ 100,2 ≤ L ≤ 1000,0 < ai < L。L為偶數。 |
?
問題鏈接:CCF201803-2 碰撞的小球
問題分析:
小球碰撞實驗視頻,? 這是一個模擬題,按照時間序列進行模擬,模擬小球的運動過程。好在每個時間單位小球只移動一個位置,處理起來就要簡單一些。模擬題關鍵在于采用什么樣的數據表示,這里給出2種解法。
? 方法一(不排序,暴力):
? 使用數組pos[i]存儲第i個球的初始位置;使用數組step[i]存儲第i個球現在的運動方向,step[i]=1表示向右走,step[i]=-1表示往左走,用加法運算就可以實現小球的移動。
? 模擬過程是按照時間序列,先計算小球的下一個位置,如果該位置為兩端則改變運動方向。再根據小球的新位置看看有沒有2個小球碰頭,有的話分別改變運動方向。只是簡單地判斷2個小球是否碰頭需要用暴力法算一下。
小球碰撞實驗報告?? 方法二(結構數組,排序):
? 如果不想用暴力,則將有關參數放入一個結構數組中,給每一個小球編號,排序后再進行模擬,輸出結果時再按照編號重新排序即可。
程序說明:(略)
題記:
質量相同兩個小球碰撞?? 沒有好辦法就暴力,沒有好辦法就模擬。這個題正好應驗了這兩句話。
?
提交后得100分的C++語言程序(方法一)如下:
/* CCF201803-2 碰撞的小球 */#include <iostream>using namespace std;const int L = 1000;
int pos[L + 1], step[L + 1];int main()
{int n, l, t;cin >> n >> l >> t;for(int i = 0; i < n; i++) {cin >> pos[i];// 開始往右走,到達兩端則回頭step[i] = 1;if(pos[i] == l || pos[i] == 0)step[i] = -step[i];}for(int i = 0; i < t; i++) {// 走一步for(int j = 0; j < n; j++) {pos[j] += step[j];// 到達兩端則回頭if(pos[j] == l || pos[j] == 0)step[j] = -step[j];}// 判斷是否碰頭,碰頭則掉頭(要避免重復比較)for(int j = 0; j < n; j++)for(int k = j + 1; k < n; k++)if(pos[k] == pos[j])step[k] = -step[k], step[j] = -step[j];}for(int i = 0; i < n; i++)cout << pos[i] << " ";cout << endl;return 0;
}
?
碰撞的小球、提交后得100分的C++語言程序(方法二)如下:
/* CCF201803-2 碰撞的小球 */#include <iostream>
#include <algorithm>using namespace std;const int N = 100;
struct Node {int id; // 小球編號int pos; // 位置int step; // 運動方向,1表示向右,-1表示向左
} b[N];bool cmp1(Node a, Node b)
{return a.pos < b.pos;
}bool cmp2(Node a, Node b)
{return a.id < b.id;
}int main()
{int n, l, t, id = 0;cin >> n >> l >> t;for(int i = 0; i < n; i++) {b[i].id = ++id;cin >> b[i].pos;// 開始往右走,到達兩端則回頭b[i].step = 1;if(b[i].pos == l || b[i].pos == 0)b[i].step = -b[i].step;}sort(b, b + n, cmp1);for(int i = 0; i < t; i++) {// 走一步for(int j = 0; j < n; j++) {b[j].pos += b[j].step;// 到達兩端則回頭if(b[j].pos == l || b[j].pos == 0)b[j].step = -b[j].step;}// 判斷是否碰頭,碰頭則掉頭(排序后只需要比較相鄰的)for(int j = 1; j < n; j++)if(b[j].pos == b[j - 1].pos)b[j].step = -b[j].step, b[j - 1].step = -b[j - 1].step;}sort(b, b + n, cmp2);for(int i = 0; i < n; i++)cout << b[i].pos << " ";cout << endl;return 0;
}
?
?
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态