题目大意:一根长度为L厘米的木棍上有n只蚂蚁每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米秒。当两只蚂蚁相撞时,二者同时掉头(掉头时间忽略不计)。给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂蚁的位置。【输入格式】由输入的第一行为数据组数。每组数据的第一行为个正整数L,T,n(0≤n≤10000)以下n行每行描述一只蚂蚁的初始位置,其中,整数x为蚂蚁距离木棍左端的距离(单位:厘米),字母表示初始朝向(L表示朝左,R表示朝右)【输出格式】对于每组数据,输出n行,按输入顺序输出每只蚂蚁的位置和朝向(Turning表示正在碰撞)。在第T秒之前已经掉下木棍的蚂蚁(好爬到木棍边缘的不算)输出 Fell off
题目思路:
这里面的一个蚂蚁在碰撞而掉头的情形,最后被看做是“对穿而过”,这种“转换思想”是非常厉害滴。。要是我有一天也有这种技能就好了。
所以在处理复杂问题上的时候,如果直接去做很复杂、很麻烦,那就应该想办法变通,比如像这道题目,我们寻找共同点,
关键在于理解存在的映射关系。
于是发现,他们的方向始终相反,速度始终相同,那么就可以看作是一样地蚂蚁。
当然处理完了之后,还有一些小细节,比如所有蚂蚁的相对位置是不变的。。。
比较烦人的是输入输出顺序。并且由于排过序了,就有可能找不到原来的位置了,所以我们需要时时刻刻记录当前第i个是原来输入时的第几个。并引入了order。
重载比较运算符,以及结构体成员构造也是需要注意的技巧。
分析:假设你在远处观察这些蚂蚁的运动,会看到什么一群密密麻麻的小黑点在移动。由于黑点太小,所以当蚂蚁因碰撞而掉头时,看上去和两个点“对穿而过”没有任何区别,换句话说,如果把蚂蚁看成是没有区别的小点, 那么只需独立计算出每只蚂蚁在T时刻的位置即可。比如,有3只蚂蚁,蚂蚁1=(1,R),蚂蚁2=(3,L),蚂蚁3=(4,L),则两秒钟之注意,虽然从整体上讲,“掉头”等价于“对穿而过”, 但对于每只蚂蚁而言并不是后,3只蚂蚁分别为(3,R)、(1,L)和(2,L)这样。蚂蚁1的初始状态为(1,R),因此一定有一只蚂蚁在两秒钟之后处于(3,R)的状态,但这只蚂蚁却不一定是蚂蚁1。换句话说,我们需要搞清楚目标状态中“谁是谁”。也许读者已经发现了其中的奥妙:所有蚂蚁的相对顺序是保持不变的,因此把所有目标位置从小到大排序,则从左到右的每个位置对应于初始状态下从左到右的每只蚂蚁。 由于原题中蚂蚁不一定按照从左到右的顺序输入,还需要预处理计算出输入中的第i只蚂蚁的序号 order
分析题中所用到的变量:
1.结构体node存蚂蚁的输入输出顺序id,蚂蚁的方向location,蚂蚁距离木棍左端的距离p
2.结构体数组node sta[10005],ed[10005];存初始和最后状态
3.int ord[10005];记录当前第i个是原来输入时的第几个
4.char to[3][10]={"L", "Turning", "R"}; 在最后输出方向时用到
ac代码:
1 #include2 #include 3 using namespace std; 4 struct node{ 5 int id;//输入顺序 6 int location;//-1,0,1 7 int p;//位置 8 }; 9 node sta[10005],ed[10005];10 int ord[10005];11 bool cmp(node x,node y)12 {13 return x.p >Case;20 for(int i=1;i<=Case;i++)21 {22 int L,T,n;23 cin>>L>>T>>n;24 25 for(int j=0;j >sta[j].p>>c;29 if(c=='L') 30 sta[j].location=-1;31 else32 sta[j].location=1; 33 sta[j].id=j;34 35 ed[j].id=0;36 ed[j].p=sta[j].p+T*sta[j].location;37 ed[j].location=sta[j].location;38 }39 sort(sta,sta+n,cmp);40 for(int j=0;j L)56 printf("Fell off\n");57 else58 printf("%d %s\n",ed[a].p, to[ed[a].location+1]);59 }60 cout<