【CF848B】 Rooter's Song

题目链接

\(solution\)

类似于蚂蚁那道题的做法

弹性碰撞相当于交换位置并继续前进,考虑一个起点\((x,0)\),时间为\(t\)出发的\(dancer\),相当于从\((x,-t)\)的坐标出发,最终所有终点位置是一定的,但是不知道与哪个\(dancer\)配对

两个\(dancer\)碰撞的条件是\(x+y\)相等,

不难发现所有相等的\((x,y)\)在一条斜率为\(-1\)的直线上,也就是说,一组发生碰撞的\(dancer\)中,一个\(dancer\)一定在另一个\(dancer\)的左上方或右下方

由于碰撞,所有\(dancer\)的相对位置不会变化,所以最终位置可以与初始位置配对了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int MAXN=100010;

inline int read(){
	int x=0; char c=getchar();
	while(c<'0') c=getchar();
	while(c>='0') x=x*10+c-'0',c=getchar();
	return x;
}

int n,w,h;

struct NODE{
	int x,y,ex,ey,id;
}a[MAXN],b[MAXN];

inline bool cmp1(NODE u,NODE v){
	return u.x+u.y>v.x+v.y||(u.x+u.y==v.x+v.y&&u.x-u.y>v.x-v.y);
}

inline bool cmp2(NODE u,NODE v){
	return u.x+u.y>v.x+v.y||(u.x+u.y==v.x+v.y&&u.ex-u.ey>v.ex-v.ey);
}

int Ansx[MAXN],Ansy[MAXN];

int main()
{
	n=read(); w=read(); h=read();
	int g,p,t;
	for(int i=1;i<=n;++i){
		g=read(); p=read(); t=read();
		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+1,a+1+n,cmp1);
	sort(b+1,b+1+n,cmp2);
	for(int i=1;i<=n;++i)
		Ansx[a[i].id]=b[i].ex,Ansy[a[i].id]=b[i].ey;
	for(int i=1;i<=n;++i)
		printf("%d %d\n",Ansx[i],Ansy[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/66-CCF-F/p/11813371.html