【Codeforces】849D. Rooter's Song
【算法】模拟
【题意】http://codeforces.com/contest/849/problem/D
给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置。(还是乖乖啃原题意去吧233)
【题解】
两个数会相撞,当且仅当xi+tj=xj+ti,即xi-ti=xj-tj。令di=xi-ti,则只有di相同的一堆数会相撞。
观察相撞规律,容易发现处理方式。处理出一堆相同的数字后,x从大到小再y从小到大放入A,y从小到大再x从大到小放入B,然后A对应从B中取位置。
给所有的y+500000就可以是y自然排在x后面,也方便判断x轴和y轴。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100010,H=500000,G=150000; struct cyc{int x,num,id;}a[maxn]; int n,x1,x2,tot,A[maxn],B[maxn],ans[maxn],anss[maxn]; bool cmp(cyc a,cyc b){return a.num<b.num||(a.num==b.num&&a.x<b.x);} int main(){ scanf("%d%d%d",&n,&x1,&x2); int u,v,w; for(int i=1;i<=n;i++){ scanf("%d%d%d",&u,&v,&w); a[i]=(cyc){v+(u-1)*H,v-w,i}; } sort(a+1,a+n+1,cmp); int l=1,m=0,r=0; a[n+1].num=0x3f3f3f3f; for(int i=1;i<=n;i++){ if(a[i].x<G)m=i;else r=i; if(a[i].num!=a[i+1].num){ tot=0; for(int j=m;j>=l;j--)A[++tot]=j; for(int j=m+1;j<=r;j++)A[++tot]=j; tot=0; for(int j=m+1;j<=r;j++)B[++tot]=j; for(int j=m;j>=l;j--)B[++tot]=j; for(int j=1;j<=tot;j++)ans[A[j]]=B[j]; l=i+1,m=i,r=i; } } for(int i=1;i<=n;i++)anss[a[i].id]=a[ans[i]].x; for(int i=1;i<=n;i++){ if(anss[i]>G)printf("%d %d\n",x1,anss[i]-H); else printf("%d %d\n",anss[i],x2); } return 0; }