CCF认证2018032-碰撞的小球

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zee_Chao/article/details/87890915

本人初学,水平有限,若有不足,恳请赐教!

根据提示可以发现题目对可能发生的情况做了大大的简化(毕竟这只是第二题……)。因此这道题主要需要我们解决的问题就是如何设计数据结构存储小球信息以及如何进行小球的移动操作和碰撞检测。

首先,在数据结构设计上,可以自定义类型来存放小球的位置和移动方向。其中,移动方向用整型数据表示,方向取1代表右移,取-1代表左移。这样小球移动后的位置信息可以更新为原来的位置数据与移动方向的和。当然,由于结构体中只有两个属性。因此可以用pair类型来代替,其中pair.first记录位置,pair.second记录方向。所有的小球用一个vector<pair<int,int>>的向量存储。

然后就是设计控制小球的移动操作和碰撞检测。根据题意,由于初始时刻没有小球位置重叠,且所有小球方向一致。因此在每个时间段内都可以先对小球做边界检测(是否触碰到了边界),然后在令小球移动。每次移动之后,利用二重嵌套循环来判断是否存在位置相同的小球(由于题目已经提示了不会存在两个以上的小球发生碰撞,因此可以放心大胆地使用)。

具体代码如下:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	int n, L, t;
	cin >> n >> L >> t;
	vector<pair<int, int>> vp(n+1); //存放小球信息
	for(int i = 1; i < n + 1; i++) //读取小球位置信息
	{
		pair<int, int> p;
		cin >> p.first;
		p.second = 1; //所有小球方向初始化为向右
		vp[i] = p;
	}
	for(int i = 1; i < t + 1; i++)
	{
		for(int j = 1; j < n + 1; j++) //边界检测及小球移动,触碰边界则先改变方向再移动
		{
			if(vp[j].first == 0 && vp[j].second == -1) vp[j].second *= -1;
			else if(vp[j].first == L&&vp[j].second == 1) vp[j].second *= -1;
			vp[j].first += vp[j].second;
		}
		for(int j = 1; j < n + 1; j++) //碰撞检测
		{
			for(int k = j + 1; k < n + 1; k++)
			{
				if(vp[j].first == vp[k].first)
				{
					vp[j].second *= -1;
					vp[k].second *= -1;
					break; //碰撞至多出现一次故可以跳出
				}
			}
		}
	}
	for(int i = 1; i < n + 1; i++)
	{
		cout << vp[i].first << ' ';
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Zee_Chao/article/details/87890915