CodeForces

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

题目大意:给出n个人行走的开始时刻,开始时间和结束时间,求每个人分别能跟多少人相遇打招呼(每两人只能打招呼一次)。

例:

输入:
3
1 1 10
5 8 2
9 9 10

输出:

2 1 1

解题思路:先按行走的开始时刻排下序,然后直接模拟判断和比他后出现的人是否可以相遇。

第一步判断前面那个人在未走完前,下一人会出现,若不出现,直接break。然后就计算当下一个人出现的时刻,前一个人的位置,然后又分种情况,两个人可能刚好在一起,有可能在他左边,也可能在他右边。刚好在一起很好,直接相遇了,若不相遇,则要判断他们是否同向,若同向,肯定不可能相遇,速度是相同的,判断是否同向,直接两个人的终点减去起点相乘是否大于0就可以,不过要注意的是:他们相乘会爆int,我就因为这个找了一个多小时才找出来,还总以为自己漏了情况。。。。反方向的话,直接计算他们的位置判断是否在他们行走的范围以内即可。

附上代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 struct node{
 8     int t;  //开始行走的时刻 
 9     int s;  //开始位置 
10     int f;  //结束位置 
11     int id; //序号 
12 }p[1005];
13 int n,cnt[1005];
14 bool comp(const node &a,const node &b)
15 {
16     return a.t<b.t;
17 }
18 
19 int main()
20 {
21     while(scanf("%d",&n)!=EOF)
22     {
23         memset(cnt,0,sizeof(cnt));
24         for(int i=0;i<n;i++)
25         {
26             scanf("%d%d%d",&p[i].t,&p[i].s,&p[i].f);
27             p[i].id=i;
28         }
29         sort(p,p+n,comp);  //按开始行走的时刻排序 
30         //cout<<endl;
31         //for(int i=0;i<n;i++)
32         //    cout<<p[i].t<<" "<<p[i].s<<" "<<p[i].f<<endl;
33         int t,pos;
34         for(int i=0;i<n-1;i++)
35         {
36             for(int j=i+1;j<n;j++)
37             {
38                 if(p[i].t+abs(p[i].f-p[i].s)<p[j].t)  //第i个人走完了,第j个人还未出现,直接break 
39                     break;
40                 t=p[j].t-p[i].t;
41                 if(p[i].f>p[i].s)
42                     pos=p[i].s+t; 
43                 else
44                     pos=p[i].s-t;  //pos为第j个人出现的时候第i个人的位置 
45                 //cout<<pos<<endl;
46                 if(pos==p[j].s)  //在j的其实位置相遇 
47                 {
48                     cnt[p[i].id]++;
49                     cnt[p[j].id]++;
50                 }
51                 else if(pos<p[j].s)
52                 {
53                     ll y=(ll)(p[i].f-p[i].s)*(ll)(p[j].f-p[j].s);
54                     if(y>0)    //两个人同向,速度相同,追不上 
55                         continue;
56                     if((p[i].f-p[i].s)<0&&(p[j].f-p[j].s)>0)  //反向但是位置不对 
57                         continue;
58                     double x=pos+(p[j].s-pos)/2.0;  //相遇位置 
59                     if(x<=p[i].f&&x>=p[j].f)
60                     {
61                         cnt[p[i].id]++;
62                         cnt[p[j].id]++;
63                         //cout<<p[i].id<<" "<<p[j].id<<endl;
64                     }
65                 }
66                 else
67                 {
68                     ll y=(ll)(p[i].f-p[i].s)*(ll)(p[j].f-p[j].s);
69                     if(y>0)
70                         continue;
71                     if((p[i].f-p[i].s)>0&&(p[j].f-p[j].s)<0)
72                         continue;
73                     double x=pos-(pos-p[j].s)/2.0;
74                     if(x<=p[j].f&&x>=p[i].f)
75                     {
76                         cnt[p[i].id]++;
77                         cnt[p[j].id]++;
78                         //cout<<p[i].id<<" "<<p[j].id<<endl;
79                     }
80                 }
81                 
82             }
83         }
84         printf("%d",cnt[0]);
85         for(int i=1;i<n;i++)
86             printf(" %d",cnt[i]);
87         printf("
");
88     }
89     return 0;
90 }
原文地址:https://www.cnblogs.com/zjl192628928/p/9408393.html