C题
1、暴力解法就是模拟,分成0.5一个可读,然后遍历坐标轴
2、bounce = 穿过去,所以关键就是维护序号的变化
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef pair<int,pair<int,int>> PIII;
typedef pair<double,pair<int,int>> PDII;//时间点 + 左边点,右边点
typedef pair<double,int> PDI;
int T = 1;
void solve(){
int n,l;
cin >> n >> l;
vector<PIII> ants;
ants.resize(n + 10);
for(int i = 1;i <= n;i++){//和蚂蚁的下标对应,就是1~n
int p,d;
cin >> p >> d;
ants[i] = {p,{d,i}};//p是距离,d是方向,i是编号
}
sort(ants.begin() + 1,ants.begin() + n + 1);//按照p排序,p小的在前面,p大的在后面
vector<PDII> changes;
vector<PDI> fall;//
for(int i = 1;i <= n;i++){
int p = ants[i].first,d = ants[i].second.first,num = ants[i].second.second;
for(int j = i + 1;j <= n;j++){
int p1 = ants[j].first,d1 = ants[j].second.first,num1 = ants[j].second.second;
if(d == 1 && d1 == 0){//相撞
double t = (double)(p1 - p) / 2;
changes.push_back({t,{num,num1}});//i是第i只蚂蚁,是编号
}
}
//计算掉落的时间
if(d == 0) fall.push_back({(double)(p),num});//0 -> d,到0是掉下去
else fall.push_back({(double)(l - p),num});//d -> l,到l是掉下去
}
sort(changes.begin(),changes.end());//交换的事件按照时间排序
//先换编号,在排序
vector<int> change_end;
change_end.resize(1010);//change_end[i] = j,表示i号蚂蚁最后交换成j号蚂蚁
for(int i = 1;i <= n;i++) change_end[i] = i;
for(auto item : changes){
int left = item.second.first,right = item.second.second;
int tmp = change_end[left];
change_end[left] = change_end[right],change_end[right] = tmp;
}
for(auto& item : fall){
int tmp = item.second;
item.second = change_end[tmp];
}
sort(fall.begin(),fall.end());//按照掉落时间排序
// for(auto item : changes) cout << item.first << ' ' << item.second.first << ' ' << item.second.second << endl;
// for(auto item : fall) cout << item.first << ' ' << item.second << endl;
//计算每个蚂蚁交换之后的序号
cout << "Case #" << T++ << ":";
for(auto item : fall){
cout << " " << item.second;
}
cout << endl;
}
int main(){
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}