CodeForces 589D Boulevard

来源:互联网 发布:淘宝的名星同款的图片 编辑:程序博客网 时间:2024/05/16 11:36

题意:n组数据t,s,f分别代表一个人从t时刻出发沿着s~f的方向行走,只有两个方向,正向或者反向,当两个人在同一时刻出现在同一位置时互相打招呼,每两个人只打一次招呼,要求输出每个人分别打多少次招呼,所以很容易理解,一道简单的数学相遇题,而因为数据n是1000以内,所以完全可以两重循环暴力出结果

因为分为两个方向,所以我考虑的情况有4种

同方向时只要t较小的在t较大的时刻的位置是合理的并且正好与t较大的时刻的人相遇即为真

反方向时我先处理出t较小的人走到较大t时的位置,然后再让其中一个走到终点,这时就可以判断两个人到达终点时的关系来辨别是否可以相遇

代码如下

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=1000+5;int n,ans[maxn];struct Edge{    int t,s,f,id;    bool operator < (const Edge &r) const    {        return t<r.t;    }} a[maxn];bool judge(Edge &a,Edge &b){    int f1,f2;    if(a.f>a.s) f1=0;    else f1=1;    if(b.f>b.s) f2=0;    else f2=1;    if(!f1&&!f2)    {        int x=a.s+b.t-a.t;        if(x>=a.s&&x<=a.f&&x==b.s) return true;        return false;    }    if(!f1&&f2)    {        if(a.s>b.s) return false;        if(a.f<b.f) return false;        int x=a.s+b.t-a.t;        if(x>a.f) return false;        if(x>b.s) return false;        int d=min(a.f-x,b.s-b.f);        int ca=x+d,cb=b.s-d;        if(ca<cb) return false;        return true;    }    if(f1&&!f2)    {        if(a.f>b.f) return false;        if(a.s<b.s) return false;        int x=a.s-(b.t-a.t);        if(x<a.f) return false;        if(x<b.s) return false;        int d=min(x-a.f,b.f-b.s);        int ca=x-d,cb=b.s+d;        if(ca>cb) return false;        return true;    }    if(f1&&f2)    {        int x=a.s-(b.t-a.t);        if(x<=a.s&&x>=a.f&&x==b.s) return true;        return false;    }}int main(){    while(~scanf("%d",&n))    {        memset(ans,0,sizeof(ans));        for(int i=1; i<=n; i++) scanf("%d%d%d",&a[i].t,&a[i].s,&a[i].f),a[i].id=i;        sort(a+1,a+1+n);        for(int i=1; i<=n; i++)            for(int j=i+1; j<=n; j++)                if(judge(a[i],a[j])) ans[a[i].id]++,ans[a[j].id]++;        printf("%d",ans[1]);        for(int i=2; i<=n; i++) printf(" %d",ans[i]);        printf("\n");    }}


0 0
原创粉丝点击