liuyiding | We have carefully selected several similar problems for you: 6170 6169 6168 6167 6166
题意:一个圆形跑道,n个人跑步,每个人有不同的起始点和速度(大小和方向均可能不同),标号1-n,当两个人相遇,标号小的将会被淘汰,问最后还剩一个人时的时间。
思路:大模拟+优先队列 首先模拟一下操场的情况,将n个人按起点的大小排序,然后用优先队列维护相邻两人之间追逐需要的时间,每次淘汰下表小得人并且更新剩下人的左右,并将新的追逐时间入队列。
ac代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN=2*1e5+1;
int n,l;
int L[MAXN],R[MAXN];
bool vis[MAXN];
struct node
{
int s;
int v;
int id;
}a[MAXN];
bool cmp(node a,node b)
{
return a.sb.time;
}
};
int gcd(int x1,int y1)
{
if(y1==0)
return x1;
return gcd(y1,x1%y1);
}
double get_time(int x1,int y1)
{
int dx=((a[y1].s-a[x1].s)%l+l)%l;
int dv=a[x1].v-a[y1].v;
if(dv<0)
{
dv=-dv;
dx=l-dx;
}
return (double)dx/dv;
}
void output(int x1,int y1)
{
int dx=((a[y1].s-a[x1].s)%l+l)%l;
int dv=a[x1].v-a[y1].v;
if(dv<0)
{
dv=-dv;
dx=l-dx;
}
int pk=gcd(dx,dv);
dx/=pk;
dv/=pk;
printf("%d/%d\n",dx,dv);
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
cin>>n>>l;
for(int i=0;i que;
node1 N;
for(int i=0;i1)
{
N=que.top();
que.pop();
int p1=N.x,p2=N.y;
if(vis[p1]||vis[p2])
continue;
if(L[p1]==p2&&R[p1]==p2)
break;
if(a[p1].id>a[p2].id)
{
vis[p2]=1;
R[p1]=R[p2];
L[R[p2]]=p1;
double tim=get_time(p1,R[p2]);
N.x=p1;
N.y=R[p2];
N.time=tim;
que.push(N);
}
else
{
vis[p1]=1;
L[p2]=L[p1];
R[L[p1]]=p2;
double tim=get_time(L[p1],p2);
N.x=L[p1];
N.y=p2;
N.time=tim;
que.push(N);
}
k++;
if(k==n)
break;
}
N=que.top();
que.pop();
int p1=N.x,p2=N.y;
output(p1,p2);
}
return 0;
}