题目大意就不说了,无论原文还是蓝书,都讲的非常明白易懂!
因为在挑战程序设计的书上看到过一个稍微简单点的蚂蚁,感觉这一类问题比较有意思,就先做了做,整理了一下内容,
整体思路:
因为蚂蚁碰撞后换返回,所以简单方法就是把蚂蚁看成走直线的,就是碰面后直穿而过,不会回头,这样和原意是等价的,这里等价是说他们的位置是等价的,也就是位置想同,不同的是两个蚂蚁“换了换身体”,只要记清楚哪个位置的蚂蚁是哪一个就可以了,所以可以用结构体把蚂蚁的方向 ,位置,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; }