其他分享
首页 > 其他分享> > ccf 201803-2 碰撞的小球

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