您的位置:首页 > 其它

CodeForces 589D --- D. Boulevard (数学题目--枚举分类讨论)

2016-08-10 23:56 549 查看

D. Boulevard

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

 Welcoming autumn evening is the best for walking along the boulevard and n people decided to do so.

 The boulevard can be represented as the axis Ox. For every person there are three parameters characterizing the behavior: ti, si, fi — the moment of time when the i-th person starts walking, the start point and the end point of the walk respectively. Each person moves in a straight line along the boulevard from si to fi with a constant speed of either 1 or  - 1 depending on the direction.

 When the i-th person appears on the boulevard at the point si she immediately starts walking towards the point fi.

 If two or more persons meet at the boulevard (they are at the same point at the same time, no matter which directions they are going) they all greet each other. Like in the normal life, every pair of people greet each other at most once.

 You task is to calculate for every person how many people she greets while walking along the boulevard.

 Please, pay attention to the fact that i-th person may meet and greet any other person at points si and fi. After a person achieves the destination point fi she moves out of the boulevard and cannot greet anyone else. The same rule applies to the start of the walk: a person cannot greet anyone until she appears on the boulevard.

Input

 In the first line there is an integer n (2 ≤ n ≤ 1000) — the number of people who decided to go for a walk.

 The following n lines contain parameters for n people. In the i-th line there are three positive integers ti, si, fi (1 ≤ ti, si, fi ≤ 106,  si ≠ fi), where ti, si, fi — the moment of time when the i-th person starts walking, the start point and the end point of the walk respectively.

Output

 The single line of the output should contain a sequence of n integers r1, r2, …, rn separated by a space, where ri denotes the number which the i-th person greets other people while walking along the boulevard.

Examples

Input

3
1 1 10
5 8 2
9 9 10


Output

2 1 1


Input

3
3 2 4
4 3 4
3 6 4


Output

2 2 2


大体题意:有n个人走在林荫大道,告诉你每个人出现的时间,起始位置,终止位置,求出每一个人最多和几个人相遇,两个人最多相遇一次,他们的速度是±1.

思路:整体思路很好想,枚举每一个人,在来一重循环,枚举他能相遇的人,如果能的ans[i]++,最后输出ans即可!

关键就在于判断相遇的函数!

我想的比较麻烦,稍微看看吧。

我把他们分成了两个线段,两个线段分成了三种情况,两个线段外离,相交,内含!

分别讨论即可! 外离肯定不相遇,相交四种方向讨论一下,内含四种情况讨论一下

其实分类讨论 讨论方向就行了,如果他们同向的话,要想相遇只能在另一个人开始的地方相遇!

如果相向的话,就可以设出相遇位置为X,解方程即可!

详细见代码:

#include<bits/stdc++.h>
using namespace std;

struct Node{
int t,s,e;
int dir;
}p[1007];
int ans[1007];
bool rev(int id1,int id2){
int t1 = p[id1].t,s1 = p[id1].s,e1 = p[id1].e;
int t2 = p[id2].t,s2 = p[id2].s,e2 = p[id2].e;
int mins = min(s1,e1),maxs = max(s1,e1);
int mins2 = min(s2,e2),maxs2 = max(s2,e2);
if (!(mins < mins2 || (mins == mins2  && maxs > maxs2)) )swap(id1,id2);
t1 = p[id1].t,s1 = p[id1].s,e1 = p[id1].e;
t2 = p[id2].t,s2 = p[id2].s,e2 = p[id2].e;
int dir1 = p[id1].dir;
int dir2 = p[id2].dir;
mins = min(s1,e1),maxs = max(s1,e1);
mins2 = min(s2,e2),maxs2 = max(s2,e2);
if (maxs < mins2)return 0;
if (maxs == mins2){
if (dir1 == 1 && dir2 == 1){ // OK
return e1-s1+t1 == t2;
}
if (dir1 == 1 && dir2 == -1){ // OK
return e1-s1+t1 == s2-e2+t2;
}
if (dir1 == -1 && dir2 == 1){ // OK
return t1 == t2;
}
if (dir1 == -1 && dir2 == -1){ // OK
return t1 == s2-e2+t2;
}

}

if (mins2 < maxs && maxs2 > maxs){
if (dir1 == 1 && dir2 == 1){ // OK
return s2-s1+t1 == t2;
}
if (dir1 == 1 &&dir2 == -1){ // OK
double t = (s2+t2+s1-t1)*1.0/2;
if (t >=e2 && t <= e1)return 1;
return 0;
}
if (dir1 == -1 && dir2 == 1){//ok
double t = s1 + t1 + s2 - t2;
t/=2;
if (t >= s2 && t <= s1)return 1;
return 0;
}
if (dir1 == -1 && dir2 ==-1){//ok
return t1 == s2-s1+t2;
}
}

if (dir1 == 1 && dir2 == 1){ // OK!
return s2-s1+t1 == t2;
}
if (dir1 == 1 && dir2 == -1){ // OK!
double t = s2+t2+s1-t1;
t/=2.0;

if (t >= e2 && t <= s2)return 1;
return 0;
}
if (dir1 == -1 &&  dir2 == 1){ // OK
double t = s1+t1+s2-t2;
t/=2.0;
if (t >= s2 && t <= e2)return 1;
return 0;

}
if (dir1 == -1 && dir2 == -1){ // OK
return t2 == s1-s2+t1;
}

}
int main(){
int n;
scanf("%d",&n);
for (int i = 0; i < n ;++i){
scanf("%d %d %d",&p[i].t,&p[i].s,&p[i].e);
if (p[i].e > p[i].s)p[i].dir = 1;
else p[i].dir = -1;

}
for (int i = 0; i < n; ++i){
for (int j = 0; j < n; ++j){
if(i == j)continue;
if (rev(i,j))ans[i] ++;
}
}
for (int i = 0 ; i < n; ++i){
if (i)printf(" ");
printf("%d",ans[i]);
}
puts("");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: