CCF认证 201803-2碰撞的小球

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
方法一:设line数组记录线段上小球信息,模拟

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3;
pair<int,int>ball[maxn];//1表示向右,-1表示向左运动
int line[maxn];//记录线段上小球信息,为0表示没有小球,否则表示小球编号(从1开始)
int main() {
	int n,l,t;cin>>n>>l>>t;
	for(int i=1;i<=n;i++){
		cin>>ball[i].first;
		ball[i].second=1;//起始向右运动
		line[ball[i].first]=i;
	}
	while(t--){
		for(int i=1;i<=n;i++){
			line[ball[i].first]=0;//小球从当前位置移走
			ball[i].first+=ball[i].second;//移动小球
			if(line[ball[i].first]){//小球即将到达的位置有其他小球,改变两球方向
				ball[i].second=-ball[i].second;
				ball[line[ball[i].first]].second=-ball[line[ball[i].first]].second;
			}
			else if(ball[i].first==0||ball[i].first==l)//撞墙
				ball[i].second=-ball[i].second;
			line[ball[i].first]=i;//小球移动到即将到达的位置处
		}
	}
	for(int i=1;i<=n;i++)
		cout<<ball[i].first<<' ';
	return 0;
}

方法二:
思路:因为小球都一样,没有区别。因此可以看作小球之间相互不影响,问题就简化成一个小球从初始位置向右按着1单位长度每秒的速度行进,当到达端点后就向反方向运动。避免了使用模拟法带来的繁琐操作。但是不知道按输入顺序的小球对应哪个值。
最终时刻小球的相对位置和开始时各小球的相对位置是一样的,第i个球的初始位置的排名为 r = d i c [ a [ i ] ] r = dic[a[i]] ,小球的最终位置的排名也为r,故 a n s [ r ] ans[r] 即为对应的位置。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3;
int a[maxn],ans[maxn],tmp[maxn];//记录开始位置、结束位置、tmp建立开始和结束位置的映射
map<int,int>dic;//第一个值表示初始位置,第二个值表示初始位置的排名
int main() {
	int n,l,t;cin>>n>>l>>t;
	for(int i=0;i<n;i++){
		cin>>a[i];tmp[i]=a[i];
		int pos=(a[i]+t)%(2*l);//t秒后小球位置
		if(pos>l)ans[i]=l-pos%l;//小球向反方向运动
		else ans[i]=pos;
	}
	sort(tmp,tmp+n);
	sort(ans,ans+n);
	for(int i=0;i<n;i++)
		dic[tmp[i]]=i;//dic记录球(递增编号)的位置
	for(int i=0;i<n;i++)
		cout<<ans[dic[a[i]]]<<' ';//dic[a[i]]为第i个球初始位置的排位
	return 0;
}
发布了99 篇原创文章 · 获赞 44 · 访问量 5511

猜你喜欢

转载自blog.csdn.net/weixin_44413191/article/details/103447953