[20200727NOIP提高组模拟T2]走路

题目大意:

  今有一数轴,有若干人在其上走,从时间$begin$开使在$s$处出现,走到$t$处后下一秒消失,任何人速度均为$1$或$-1$,现请你求出任意一人可与多少人相遇.两人相遇,当且仅当他们同时同地存在,且任意两人至多相遇一次.

solution:

  简单线性规划,以时间作为$x$轴,位置作为$y$轴,每人的行走状态可以用一线段表示.先将出现时间按从小到大排序,预处理每人速度.然后一一枚举两人,取出现时间交集,端点控制判断交集处线段是否相交即可.

code:

   

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<ctime>
 9 #include<map>
10 #define R register
11 #define next exnttttttttt
12 #define debug puts("mlg")
13 using namespace std;
14 typedef long long ll;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 inline ll read();
18 inline void write(ll x);
19 inline void writesp(ll x);
20 inline void writeln(ll x);
21 ll n;
22 struct node{
23     ll begin,end,s,t,v,name1;//name1为排序前的编号,begin为出现时间,end为走到终点时间,s为启动,t为终点,v为速度1/-1
24     bool operator <(const node X)const{return begin<X.begin;}
25 }pr[1100];
26 ll ans[1100];
27 inline bool check(ll i,ll j){
28     if(pr[i].end<pr[j].begin) return false;
29     ll Beg=pr[j].begin,End=min(pr[i].end,pr[j].end);
30     ll Y1_beg=pr[i].s+pr[i].v*(Beg-pr[i].begin),Y2_beg=pr[j].s+pr[j].v*(Beg-pr[j].begin);
31     ll Y1_end=Y1_beg+(End-Beg)*pr[i].v,Y2_end=Y2_beg+(End-Beg)*pr[j].v;
32     return (Y1_beg-Y2_beg)*(Y1_end-Y2_end)<=0;
33 }
34 int main(){
35     freopen("walk.in","r",stdin);
36     freopen("walk.out","w",stdout);
37     n=read();
38     for(R ll i=1;i<=n;i++) pr[i].name1=i,pr[i].begin=read(),pr[i].s=read(),pr[i].t=read(),pr[i].end=pr[i].begin+abs(pr[i].t-pr[i].s),pr[i].v=(pr[i].s<pr[i].t?1:-1);
39     sort(pr+1,pr+n+1);
40     for(R ll i=1;i<=n;i++){
41         for(R ll j=i+1;j<=n;j++){
42             if(check(i,j)) ++ans[pr[i].name1],++ans[pr[j].name1];
43         }
44     }
45     for(R ll i=1;i<=n;i++) writesp(ans[i]);
46 }
47 inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
48 inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
49 inline void writesp(ll x){write(x);putchar(' ');}
50 inline void writeln(ll x){write(x);putchar('\n');}

 

  

posted @ 2020-07-27 14:10  月落乌啼算钱  阅读(95)  评论(0编辑  收藏  举报