题目描述
给兔兔们染完颜色后,Hzy把n只颜色不同的兔兔放在了一根长度为L=10n的木棍的不同位置(每只兔兔的位置在[0,L]之间)上,让她们做做运动。
在最开始的时候,Hzy会给每只兔兔指定一个方向,所有的兔兔都会乖乖地按照Hzy给她们指定的方向走(速度为每秒一个单位长度)。而当两只兔兔相遇(到达相同的位置)时,它们会同时掉头(掉头的时间忽略不计),下一秒她们会朝着相反的方向走。如果某只兔兔走到了木棍的边缘(位置0或者位置L),则她也会掉头,下一秒她会朝着相反的方向走。
现在,兔兔们想知道,T秒后她们分别在什么位置。
输入
第一行两个整数n、T,分别表示兔兔的数量和运动的秒数。
之后的n行,每行两个整数,依次表示从左到右每只兔兔的位置和朝向(−1表示向左,1表示向右)。
输出
输出n行,依次表示每只兔兔(与输入中的顺序对应)的位置。
样例输入
3 2
1 -1
5 1
9 -1
样例输出
1
7
7
提示
对于100%的数据,1≤n≤105,0≤T≤1018,兔兔的起始位置均为奇数。
【小结】:
看完题目,我第一感觉就认为这个题目好像在哪里做过一样。
没错,我想到的就是poj 1852
这个题目有点神似,因为问题都是相遇之后折返走,然后poj 1852 .
这题的做法,直接就是把两只蚂蚁折返走,看作两只蚂蚁互相穿过去。
这题的答案就浮现出来了。
这是第一个想法,然后麻烦的问题又来了,它说要输出小兔子最后所在的位置。
是按输入的顺序来输出。
问题是:蚂蚁这个题目,只能是看作穿过去罢了,但是两只蚂蚁的身份明显就交换了,
而且t给的很大,无法枚举跟踪每只蚂蚁的行踪。
所以,这时候引入第二个概念。
我初中做到一个期末考试的数学题。
我已经找不到原题给大家了,
然后这个题目的意思是,两球相遇,然后一个球以匀速前进,然后另外一个球相遇后折返。
问:另外一个球移动的距离。
当时我真的不会做这个题,后来想想,也就那么简单,
大家思考一下,其实即使两只蚂蚁身份改变了,但是相对来说,其实每一只蚂蚁都在自己所在的区域下运动。
所以肯定答案只要把所有位置求出,最后排序即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
typedef struct Node{
int No,x,flag;
/*bool operator < (const Node &p)const {
return x<p.x;
}*/
}Node;
Node a[N];
bool cmp(Node a,Node b){
return a.x<b.x;
}
int main()
{
int n,L,t;
ll tt;
//freopen("stick.in", "r", stdin); freopen("stick.out", "w", stdout);
scanf("%d%lld",&n,&tt);
L=10*n;
t=(int)(tt%((ll)(2*L)));
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].x,&a[i].flag);
a[i].No=i;
}
for(int i=0;i<n;i++){
if(a[i].flag==-1){
if(a[i].x>=t){
a[i].x=a[i].x-t;
}else if(a[i].x<t&&t<a[i].x+L){
a[i].x=t-a[i].x;
}else{
a[i].x=2*L-t+a[i].x;
}
}
else if(a[i].flag==1){
if(t+a[i].x<=L){
a[i].x=t+a[i].x;
}else if(L<t+a[i].x&&t+a[i].x<=2*L){
a[i].x=2*L-t-a[i].x;
}else if(t+a[i].x>2*L){
a[i].x=(t+a[i].x)%(2*L);
}
}
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++){
printf("%lld\n",a[i].x);
}
return 0;
}