ccf 201803-2 碰撞的小球
作者:互联网
这道题我自己做了之后百度了一波,发现一般都是用一个大循环一秒一秒模拟,就想着写篇博客记录一下自己的想法。
题目说n个小球开始均以1单位长度每秒的速度向右运动,端点处反向、小球相遇时反向,问t秒后小球位置。
揣摩一下题意,就会发现,小球自始至终都不会越过其它小球,也就是说n个小球的相对位置(左右顺序)总是不变的(初始位置最小的小球经过 t 秒后依然最小)。
因而我们在求解过程中不必在意小球编号,只需直接求出所有小球末位置即可。
至于小球相遇时反向,由于小球可看做质点,从视觉上就想两个小球相互穿过、速率不变,因此也不必考虑。
需要注意的是:由于输入的小球位置未必是有序的,因此不能将所求得的末位置简单排序后直接输出。
下面代码中,用a[i]存储第 i (i 从0开始)个小球初始位置,同时求出该小球在不受其它小球干扰情况下移动 t 个单位后的位置,存入b[i](未必是第 i 个小球的末位置)。
r[i](排序后)按初始位置从小打到大存储小球编号。
b[i]从小到大排序。
然后将(数轴上从左至右数)数组a中第 i 个小球的初始位置更改为最终位置,即a[r[i]]=b[i]。
代码如下:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 const int N=100; 7 int a[N],b[N],r[N]; 8 bool cmp(int x,int y) 9 { 10 return a[x]<a[y]; 11 } 12 int main() 13 { 14 int n,L,t,k=0; 15 cin>>n>>L>>t; 16 t%=2*L; 17 for(int i=0;i<n;i++){ 18 scanf("%d",&a[i]); 19 if(a[i]+t<=L)b[i]=a[i]+t; 20 else if(a[i]+t<=2*L)b[i]=L-(a[i]+t-L); 21 else b[i]=a[i]+t-2*L; 22 r[i]=i; 23 } 24 sort(r,r+n,cmp); 25 sort(b,b+n); 26 for(int i=0;i<n;i++){ 27 a[r[i]]=b[i]; 28 } 29 cout<<a[0]; 30 for(int i=1;i<n;i++){ 31 printf(" %d",a[i]); 32 } 33 return 0; 34 }
ps:真的好喜欢 sort 啊哈哈哈哈!!!!
标签:include,int,位置,小球,排序,ccf,201803,初始 来源: https://www.cnblogs.com/zbhfz/p/11336638.html