CodeForces 589D Boulevard (一维区间判断相交 非线段交做法)

Boulevard


题意:n个人在一位坐标轴上,每个人都有一个起点终点,开始时间,每个人遇到其他人时都会问候一次,每两个人最多问候一次,问每个人在他们的起点到重点的时间内问候了几人

解析:由于n的范围不是很大,所以枚举每个人的做法n*n完全可以,那么接下来就只需要判断两两之间是否有交集就行了,

我是这样解决这个问题的,每个人可以向左向右开始走,那么每两个人就有,左左,右右,左右,右左,四种组合情况,对于每种组合情况,首先确定他们的最小交区间,

左左和右右相遇当且仅当他们在交区间上的开始时间相同,左右和右左的情况相遇当且仅当他们在区间上的时间段有交集,那么这样问题就迎刃而解了。


附未优化的代码:

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f


struct node
{
    int l,r;
    int t;
} c[1005];

int ans[1005];

bool check1(int x,int y)
{
    if(c[x].l>c[y].l) swap(x,y);
    int a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a>b) swap(a,b);
    if(a1>b1) swap(a1,b1);
    int l=max(a,a1);
    int r=min(b,b1);
    int t1=c[x].t+abs(l-c[x].l),t2=c[x].t+abs(r-c[x].l);
    int t3=c[y].t+abs(l-c[y].l),t4=c[y].t+abs(r-c[y].l);
    if(t3>t4) swap(t3,t4);
    if(t1>t2) swap(t1,t2);
    if(t1>t3)
    {
        swap(t1,t3);
        swap(t2,t4);
    }
    if(t1==t3) return  true;
    return false;
}

bool check2(int x,int y)
{
    if(c[x].l>c[y].l) swap(x,y);
    int a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a>b) swap(a,b);
    if(a1>b1) swap(a1,b1);
    int l=max(a,a1);
    int r=min(b,b1);
    int t1=c[x].t+abs(c[x].l-r),t2=c[x].t+abs(c[x].l-l);
    int t3=c[y].t+abs(c[y].l-r),t4=c[y].t+abs(c[y].l-l);
    if(t3>t4) swap(t3,t4);
    if(t1>t2) swap(t1,t2);
    if(t1>t3)
    {
        swap(t1,t3);
        swap(t2,t4);
    }
    if(t1==t3) return true;
    return false;
}


bool check3(int x,int y)
{
    if(c[x].l>c[y].l) swap(x,y);
    int a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a>b) swap(a,b);
    if(a1>b1) swap(a1,b1);
    int l=max(a,a1);
    int r=min(b,b1);
    int t1=c[x].t+abs(l-c[x].l),t2=c[x].t+abs(r-c[x].l);
    int t3=c[y].t+abs(c[y].l-r),t4=c[y].t+abs(c[y].l-l);
    if(t3>t4) swap(t3,t4);
    if(t1>t2) swap(t1,t2);
    if(t1>t3)
    {
        swap(t1,t3);
        swap(t2,t4);
    }
    if(t2>=t3) return true;
    return false;
}

bool check4(int x,int y)
{
    if(c[x].l>c[y].l) swap(x,y);
    int a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a>b) swap(a,b);
    if(a1>b1) swap(a1,b1);
    int l=max(a,a1);
    int r=min(b,b1);
    int t1=c[x].t+abs(c[x].l-r),t2=c[x].t+abs(c[x].l-l);
    int t3=c[y].t+abs(l-c[y].l),t4=c[y].t+abs(r-c[y].l);
    if(t3>t4) swap(t3,t4);
    if(t1>t2) swap(t1,t2);
    if(t1>t3)
    {
        swap(t1,t3);
        swap(t2,t4);
    }
    if(t2>=t3) return true;
    return false;
}

bool judge(int x,int y)
{
    int a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a>b) swap(a,b);
    if(a1>b1) swap(a1,b1);
    if(a1<a)
    {
        swap(a1,a);
        swap(b,b1);
    }
    if(!(b>=a1)) return false;
    a=c[x].l,b=c[x].r,a1=c[y].l,b1=c[y].r;
    if(a<=b&&a1<=b1)  return check1(x,y);
    else if(a>=b&&a1>=b1) return check2(x,y);
    else if(a<=b&&a1>=b1) return check3(x,y);
    else return check4(x,y);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(ans,0,sizeof ans);
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d",&c[i].t,&c[i].l,&c[i].r);
        }

        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                if(judge(i,j)) ans[j]++, ans[i]++;;
            }
        }
        for(int i=0; i<n; i++)
        {
            printf("%d",ans[i]);
            if(i!=n-1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值