https://www.luogu.com.cn/problem/UVA10881
给出若干只蚂蚁的初始位置和方向,他们的爬行速度都是 1 1 1,相遇时同时掉头,问经过若干时间之后的位置和朝向
- 我们首先可以发现,因为蚂蚁只要相遇就会掉头,所以他们的相对位置肯定不会变,也就是说原来如果 2 2 2在 1 1 1和 3 3 3中间,那么无论怎么走, 2 2 2还是在 1 1 1和 3 3 3中间
- 接下来的考虑比较巧妙,两只蚂蚁相遇我们可以看作这两只蚂蚁对穿而过,那么我们也就可以当作这只蚂蚁一直在往一个方向走,这样看使这个问题一下子变的简单了起来,接下来我们只需要把蚂蚁刚开始的位置和最后的位置对应上就可以了,这可以通过对位置从小到大排序来实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
struct ants{
int p;
int dir;
int id;
bool operator <(ants &x)const {
return p < x.p;
}
}before[MAXN], after[MAXN];
int order[MAXN];
int main(){
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int n, t, l, N, p, d;
char c;
cin >> N;;
for(int _=1;_<=N;_++){
cin >> l >> t >> n;
cout << "Case #" << _ << ":\n";
for(int i=1;i<=n;i++){
cin >> p >> c;
d = (c == 'L' ? -1 : 1);
before[i] = ants({
p, d, i});
after[i] = ants({
p + t * d, d, 0});
}sort(before + 1, before + 1 + n);
for(int i=1;i<=n;i++){
order[before[i].id] = i;
}
sort(after + 1, after + 1 + n);
for(int i=1;i<n;i++){
if(after[i].p == after[i + 1].p){
after[i].dir = after[i + 1].dir = 0;
}
}
for(int i=1;i<=n;i++){
int id = order[i];
if(after[id].p < 0 || after[id].p > l){
cout << "Fell off\n";
}else{
cout << after[id].p << ' ';
if(after[id].dir == 0) cout << "Turning\n";
else if(after[id].dir == 1) cout << "R\n";
else cout << "L\n";
}
}
cout << '\n';
}
return 0;
}