题目大意就不说了,无论原文还是蓝书,都讲的非常明白易懂!
因为在挑战程序设计的书上看到过一个稍微简单点的蚂蚁,感觉这一类问题比较有意思,就先做了做,整理了一下内容,
整体思路:
因为蚂蚁碰撞后换返回,所以简单方法就是把蚂蚁看成走直线的,就是碰面后直穿而过,不会回头,这样和原意是等价的,这里等价是说他们的位置是等价的,也就是位置想同,不同的是两个蚂蚁“换了换身体”,只要记清楚哪个位置的蚂蚁是哪一个就可以了,所以可以用结构体把蚂蚁的方向 ,位置,id(也就是输入顺序)记录下来,再有一点是初始状态的蚂蚁和末始状态的蚂蚁是相对不变的,也就是从左到右数初始蚂蚁和数末始蚂蚁都是一样的,所以在把蚂蚁结构体根据位置进行排序,之所以进行排序,是因为要找到两个位置相同的蚂蚁,因为这样的蚂蚁比较特殊,要输出Turning,弄完之后,在根据ID从小到大输出就可以了!
收获:
1.新的结构体赋值方法:(把一组数据强制转换到指定结构体)
before[i] = (ant){i,d,l};
after[i] = (ant){0,d,l + T * d};
2.结构体排序(可自定义根据结构体内部某个元素的大小进行排序!)
例如:在结构体内部加入:(loc可以换成其他的元素)
bool operator < (const ant &a) const {
return loc < a.loc;
}
3.order[before[i].id] = i;//记录指定id的位置:例如order[0]就是id = 0的的位置!以便下面的after输出!
4.简化代码数量:找到输出的共性后减少代码的书写:
例如:
const char str[4][10] = {"L","Turning","R"};,根据左 = -1,,右 = 1,转向 = 0,进行输出!
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10000 + 5;
struct ant
{
int id,dir,loc;
bool operator < (const ant &a) const {
return loc < a.loc;
}
}before[maxn],after[maxn];
int order[maxn];
const char str[4][10] = {"L","Turning","R"};
int main()
{
//freopen("out.txt","w",stdout);
int k,L,T,n,d,l;
char ch;
scanf("%d",&k);
for (int cont = 1; cont <= k; ++cont){
scanf("%d%d%d",&L,&T,&n);
printf("Case #%d:\n",cont);
for (int i = 0 ; i < n; ++i){
scanf("%d %c",&l,&ch);
d = (ch == 'R' ? 1 : -1);
before[i] = (ant){i,d,l};
after[i] = (ant){0,d,l + T * d};
}
sort (before,before + n);
for(int i = 0; i < n; ++i)
order[before[i].id] = i;//记录指定id的位置:例如order[0]就是id = 0的的位置!以便下面的after输出!
sort (after, after + n);
for (int i = 0; i < n - 1; ++i)
if (after[i].loc == after[i + 1].loc)after[i].dir = after[i + 1].dir = 0;
for (int i = 0; i < n; ++i){
int a = order[i];
if (after[a].loc < 0 || after[a].loc > L)printf("Fell off\n");
else printf("%d %s\n",after[a].loc,str[after[a].dir + 1]);
}
printf("\n");
}
return 0;
}