【cf849D】Rooter's Song(思维)

D. Rooter's Song

题意

x轴、y轴上有n个人,第i个人(g_i==1)则坐标为((p_i,0))否则((0,p_i))(t_i)秒后垂直所在坐标轴出发,到达边界x=w,或者y=h停止,速度都是1。
两个人相撞则方向互换。问最后每个人的位置。

题解

t秒后出发等价于位置往后移动t,起点就是x=p,y=-t,或者x=-t,y=p。然后x+y相等的点就是会相撞的,他们的终点位置会发生一些交换。
x+y相等的起点是在一条直线上,每个点撞来撞去其实守住了自己的相对位置,上面的还是在上面,左边的还是在左边。所以分别对应了一样排序好的终点位置。

代码

const int N=201000;
struct node{
	int x,y,ex,ey,i;
}a[N],b[N];
int ansx[N],ansy[N];
bool cmp(node a,node b){
	return a.x+a.y<b.x+b.y || a.x+a.y==b.x+b.y && a.x-a.y<b.x-b.y;
}
bool cmp2(node a,node b){
	return a.x+a.y<b.x+b.y || a.x+a.y==b.x+b.y && a.ex-a.ey<b.ex-b.ey;
}
int main() {
	int n,w,h;
	sf(n);sf(w);sf(h);
	rep(i,0,n){
		int g,p,t;
		sf(g);sf(p);sf(t);
		if(g==1)
			a[i]=(node){p,-t,p,h,i};
		else
			a[i]=(node){-t,p,w,p,i};
		b[i]=a[i];
	}
	sort(a,a+n,cmp);
	sort(b,b+n,cmp2);
	rep(i,0,n){
		ansx[a[i].i]=b[i].ex;
		ansy[a[i].i]=b[i].ey;
	}
	rep(i,0,n) printf("%d %d
",ansx[i],ansy[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/flipped/p/7467571.html