题目描述
有许多蚂蚁在一根无限长的木棍上,每一只蚂蚁都有一个初始位置和初始朝向(任意两只蚂蚁的初始位置不同)。蚂蚁们以每秒一个单位的速度向前移动,当两只蚂蚁相遇时,它们会掉头(掉头时间忽略不计)。现给出每只蚂蚁的初始位置和初始朝向,请你计算出它们在t秒后的位置和朝向。
输入输出格式
输入格式:
第一行,两个空格隔开的整数n,t(代表蚂蚁数n和时间t)
第2~n+1行每行两个整数,第i+1行代表第i只蚂蚁的初始位置ai(ai的绝对值在1000000以内)及初始朝向bi(bi=1时蚂蚁朝右,bi=-1时蚂蚁朝左)
输出格式:
n行,每行两个整数,第i行代表t秒后第i只蚂蚁的位置及朝向(-1表示朝左,1表示朝右,0表示正在转向中)
这道题目首先看起来没有丝毫头绪,但是只要掌握了要点之后还是很简单的,
1.计算所有小球位置时,可以等效于小球相遇时是直接穿过去的。
2.按照距离排序后,运动前小球在第几的位置,运动后小球还是第几的位置,并不会改变。
这道题比较坑的就是在输入的时候,第一个输入的小球并不一定是在最左边的,所以需要记录每一个小球初始位置是第几,最后输出时就就简单了,下面的代码还会有更详细的注释。
#include<bits/stdc++.h>
using namespace std;
int n,t;
//声明一个蚂蚁结构体,
struct ant{
int pos;//蚂蚁位置
int dir;//蚂蚁方向
int index;//代表是第几只蚂蚁
};
ant ants[100005];
map<int,int> mp;//mp[i]=j,代表的意思是i这个位置的蚂蚁数量为j
map<int,int> m;//m[i]=j,代表的意思是按照距离排序后
//第i只蚂蚁排第j
bool cmp(ant a,ant b){
return a.pos<b.pos;
}
int main()
{
cin>>n>>t;
for(int i=1;i<=n;i++){
cin>>ants[i].pos>>ants[i].dir;
ants[i].index=i;//index代表了第几只蚂蚁
}
sort(ants+1,ants+1+n,cmp);//按照位置排序
for(int i=1;i<=n;i++){
m[ants[i].index]=i;//排序后,就可以知道每一只蚂蚁的顺序了
}
//模拟每一只蚂蚁
for(int i=1;i<=n;i++){
if(ants[i].dir==1){
ants[i].pos+=t;
}
else{
ants[i].pos-=t;
}
mp[ants[i].pos]++;//题目中说明相遇就是正在转向,
//相遇即都处于同一个位置,所以一个位置如果有两只
//蚂蚁,就代表了正在转向。
}
//模拟蚂蚁走之后,需要按照位置再次排序。
sort(ants+1,ants+1+n,cmp);
for(int i=1;i<=n;i++){
//m[i]代表的就是第i只蚂蚁的位置顺序
cout<<ants[m[i]].pos<<" ";
if(mp[ants[m[i]].pos]!=1){
cout<<0;
}
else{
cout<<ants[m[i]].dir;
}
cout<<endl;
}
}
如果有我没有讲清楚的地方,或者大家有更好的方法,可以在下面一起讨论。