题意:有n个机器人在二维平面内,第i个机器人有一个初始坐标(xi,yi)和一个行走方向,用‘U’,‘D’,‘L’,‘R’表示上下左右;
每个机器人被其他机器人碰到才能动,刚开始只有第一个机器人能动;问T时间后每个机器人的坐标。
数据范围:
1<=n<=100000
0<=T<=10^18
0<=xi,yi<=10^9
分析:
由于每个点都有一个方向,将每个点与自己方向上的所有点连边,可以发先,题目转换成求1到其他所有点的最短时间,
最后用T-dis[i]得到剩余时间。xi,yi太大,所以离散化,然后把每个x上,每个y上的点存下来排个序,排完序后就是建
边了,但是直接将每个点与自己方向上的所有点连边有点炸,比如点全在一个x或y上且方向一样,这样就有n^2条边,
所以我们建边的时候可以将每个点与自己(a点)方向上下一个同向的点(b点)之间的点连边,因为b点与a点同向,
a就没有必要向b以后的点连边。最后跑遍dijkstra。
1<=n<=100000
0<=T<=10^18
0<=xi,yi<=10^9
分析:
由于每个点都有一个方向,将每个点与自己方向上的所有点连边,可以发先,题目转换成求1到其他所有点的最短时间,
最后用T-dis[i]得到剩余时间。xi,yi太大,所以离散化,然后把每个x上,每个y上的点存下来排个序,排完序后就是建
边了,但是直接将每个点与自己方向上的所有点连边有点炸,比如点全在一个x或y上且方向一样,这样就有n^2条边,
所以我们建边的时候可以将每个点与自己(a点)方向上下一个同向的点(b点)之间的点连边,因为b点与a点同向,
a就没有必要向b以后的点连边。最后跑遍dijkstra。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 100010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct edge {
int v,w,next;
}e[Mm];
int tot,head[Mn];
void addedge(int u,int v,int w) {
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot++;
}
struct point {
int x,y;
char c;
point(){}
point(int x,int y,char c):x(x),y(y),c(c){}
}po[Mn];
struct vtv {
int a,id;
vtv(){}
vtv(int a,int id):a(a),id(id){}
bool operator<(const vtv &x) const {
return x.a>a;
}
};
struct node {
int v;
ll cost;
node(int v,ll cost) : v(v),cost(cost) {};
bool operator <(const node x) const {
return cost>x.cost;
}
};
int vis[Mn],n;
ll dis[Mn];
void dijstra(int st) {
priority_queue<node> q;
for(int i=1;i<=n;i++) dis[i]=10e17;
CLR(vis,0);
dis[st]=0;
q.push(node(st,0));
while(!q.empty()) {
node tmp=q.top();
q.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u]; i!=-1; i=e[i].next) {
int v=e[i].v;
ll cost=e[i].w;
if(!vis[v]&&dis[v]>dis[u]+cost) {
dis[v]=dis[u]+cost;
q.push(node(v,dis[v]));
}
}
}
}
void init() {
tot=0;
CLR(head,-1);
}
int h[Mn],w[Mn];
vector<vtv> vh[Mn],vw[Mn];
int main() {
ll T;char s[2];
init();
scanf("%d%lld",&n,&T);
int hcnt=0,wcnt=0;
for(int i=1;i<=n;i++) {
int x,y;
scanf("%d%d%s",&x,&y,s);
h[hcnt++]=x;
w[wcnt++]=y;
po[i]=point(x,y,s[0]);
}
sort(h,h+hcnt);
sort(w,w+wcnt);
int h_cnt=unique(h,h+hcnt)-h;
int w_cnt=unique(w,w+wcnt)-w;
for(int i=1;i<=n;i++) {
int posx=lower_bound(h,h+h_cnt,po[i].x)-h;
int posy=lower_bound(w,w+w_cnt,po[i].y)-w;
vh[posx].push_back(vtv(posy,i));
vw[posy].push_back(vtv(posx,i));
}
int u,v;
for(int i=0;i<h_cnt;i++) {
u=-1;
sort(vh[i].begin(),vh[i].end());
for(int j=0;j<vh[i].size();j++) {
int id=vh[i][j].id;
if(u!=-1) addedge(u,id,po[id].y-po[u].y);
if(po[id].c=='U') u=id;
}
v=-1;
for(int j=vh[i].size()-1;j>=0;j--) {
int id=vh[i][j].id;
if(v!=-1) addedge(v,id,po[v].y-po[id].y);
if(po[id].c=='D') v=id;
}
}
for(int i=0;i<w_cnt;i++) {
u=-1;
sort(vw[i].begin(),vw[i].end());
for(int j=0;j<vw[i].size();j++) {
int id=vw[i][j].id;
if(u!=-1) addedge(u,id,po[id].x-po[u].x);
if(po[id].c=='R') u=id;
}
v=-1;
for(int j=vw[i].size()-1;j>=0;j--) {
int id=vw[i][j].id;
if(v!=-1) addedge(v,id,po[v].x-po[id].x);
if(po[id].c=='L') v=id;
}
}
dijstra(1);
for(int i=1;i<=n;i++) {
ll ans=max(T-dis[i],0LL);
ll x=po[i].x,y=po[i].y;
if(po[i].c=='U') y+=ans;
if(po[i].c=='D') y-=ans;
if(po[i].c=='L') x-=ans;
if(po[i].c=='R') x+=ans;
printf("%lld %lld\n",x,y);
}
return 0;
}