您的位置:首页 > 其它

CodeForces 589D Boulevard (模拟)

2016-08-11 10:21 399 查看
题意: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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学 暴力