题目就不再写了,直接开始
【分析】蚂蚁碰撞掉头,其实不用考虑掉头问题,直接让“掉头”等价于“对穿而过”,
然后调换它们的状态(感觉像是障眼法hhh),只要分清楚“谁是谁”。因为“掉头”,所以蚂蚁
的相对顺序是不变的,因此把所有目标位置从小到大排序,则从左到右的每个位置都对应初始
状态的每只蚂蚁的位置。由于原题中每只蚂蚁不一定按照从左到右顺序输入,还需要预处理
计算输入中的第i只蚂蚁的序号order[i] 。
【代码】
//2019.4.21 蚂蚁 #include <iostream> #include <algorithm> using namespace std; const int maxn = 10000 + 5; struct Ant { int id;//输入顺序 int p;//位置 int d;//朝向 -1:左;0:转身中;1:右 bool operator < (const Ant& a) const { return p < a.p; } }before[maxn],after[maxn]; const char dirName[][10] = { "L","Turning","R" }; int order[maxn];//输入第i只蚂蚁是终态中左数第order[i]只蚂蚁 int main() { int k; scanf_s("%d", &k); for (int kase = 1; kase <= k; kase++) { int L, T, n; cout << "Case #" << k << ": "; scanf_s("%d%d%d", &L, &T, &n); for (int i = 0; i < n; i++) { int p, d; char c; scanf_s("%d %c", &p, &c); d = (c == 'L' ? -1 : 1); before[i] = { i,p,d }; after[i] = { 0,p + T*d,d };//这里id是未知的 } //分清楚对穿后谁是谁,order数组对应的映射关系 sort(before, before + n); for (int i = 0; i < n; i++) order[before[i].id] = i; //计算终态 sort(after, after + n);//“对穿而过” for (int i = 0; i < n - 1; i++)//修改碰撞中的蚂蚁的方向 if (after[i].p == after[i + 1].p) after[i].d = after[i + 1].d = 0; //输出结果 for (int i = 0; i < n; i++) { int a = order[i]; if (after[a].p<0 || after[a].p>L) cout << "Fell off "; else cout << after[a].p << " " << dirName[after[a].d + 1] << " "; } cout << " "; } return 0; }