uva 10881蚂蚁(思维题)---理清关系

题目大意:一根长度为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 #include<iostream>
 2 #include<algorithm>
 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<y.p;
14 }
15 char to[][10]={"L", "Turning", "R"};
16 int main()
17 {
18     int Case;
19     cin>>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<n;j++)
26         {
27             char c;
28             cin>>sta[j].p>>c;
29             if(c=='L') 
30             sta[j].location=-1;
31             else
32             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<n;j++)
41         {
42             ord[sta[j].id]=j;
43         }
44         sort(ed,ed+n,cmp);
45         
46         for(int j=0;j<n;j++)
47         {
48             if(ed[j].p==ed[j+1].p)
49             ed[j].location=ed[j+1].location=0;
50         }
51         printf("Case #%d:\n",i);
52         for(int j=0;j<n;j++)
53         {
54             int a=ord[j];
55             if(ed[a].p<0||ed[a].p>L)
56             printf("Fell off\n");
57             else
58             printf("%d %s\n",ed[a].p, to[ed[a].location+1]);
59         }
60         cout<<endl;
61      } 
62  } 

猜你喜欢

转载自www.cnblogs.com/Aiahtwo/p/10922076.html