codeforces 589d(相遇问题)

题目链接:http://codeforces.com/problemset/problem/589/D

题意:给出n个人行走的开始时间和结束时间,求每个人分别能跟多少人相遇打招呼。

分析:两个人行走无非四种情况,同向两种:-> -> 和  <-  <-反向两种-> <- 和<-  ->分情况推他们相遇的条件即可,我是列方程求解的。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
#include<vector>
#include<cmath>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1000 + 10;
const int maxt = 1e6 + 10;
const double eps = 0.00000000000001;
const int inf = 0x3f3f3f3f;
struct person
{
    int num,t,b,e,time;
}p[maxn];
int hellow[maxn];
bool check1(int a,int b, int c, int d)//看区间[a,b]与区间[c,d]是否有交集
{
    if(c <= a && b <= d) return true;
    if(a <= c && c <= b) return true;
    if(a <= d && d <= b) return true;
    return false;
}
bool check2(double t1, double t11, double t2, double t22, double t)//判断t是否同时在区间[t1,t2]和区间[t11,t22]内
{
    return t >= t1 && t <= t11 && t >= t2 && t <= t22;
}
int main()
{
    int k;
    while(~scanf("%d",&k))
    {
        memset(hellow, 0, sizeof(hellow));
        memset(p, 0, sizeof(p));
        for(int i = 0; i < k; i++)
        {
            scanf("%d%d%d",&p[i].t, &p[i].b, &p[i].e);
        }
        for(int i = 0; i < k; i++)//两两看是否相遇
        {
            for(int j = i + 1; j < k; j++)
            {
                int t1 = p[i].t, t11 = p[i].t + abs(p[i].e - p[i].b);//t1:第i个人开始的时间  t11:第i个人结束的时间
                int t2 = p[j].t, t22 = p[j].t + abs(p[j].e - p[j].b);//同上
                int fi = p[i].b <= p[i].e ? 1 : -1;
                int fj = p[j].b <= p[j].e ? 1 : -1;
                int b1 = p[i].b, e1 = p[i].e, b2 = p[j].b, e2 = p[j].e;
                if(fi == 1 && fj == 1)//->  ->
                {
                    if(t1 - b1 == t2 - b2 && check1(t1,t11,t2,t22))
                    {
                        hellow[i]++,hellow[j]++;
                    }

                }
                if(fi == 1 && fj == -1)//-> <-
                {
                    double t = (double)(t1 - b1 + t2 + b2);
                    t /= 2;
                    if(check2(t1,t11,t2,t22,t))
                    {
                        hellow[i]++,hellow[j]++;
                    }
                }
                if(fi == -1 && fj == 1)//<- ->
                {
                    double t = (double)(t1 + b1 + t2 - b2);
                    t /= 2;
                    if(check2(t1,t11,t2,t22,t))
                    {
                        hellow[i]++,hellow[j]++;
                    }
                }
                if(fi == -1 && fj == -1)//<-  <-
                {
                    if(t1 + b1 == t2 + b2 &&  check1(t1,t11,t2,t22))
                    {
                        hellow[i]++,hellow[j]++;
                    }
                }
            }
        }
        for(int i = 0; i < k; i++)
        {
            if(i) printf(" ");
            printf("%d",hellow[i]);
        }
        printf("\n");
    }
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值