HDU2297 Run (思维题+单调性)

Run

Since members of Wuhan University ACM Team are lack of exercise, they plan to participate in a ten-thousand-people Marathon. It is common that the athletes run very fast at first but slow down later on. Start from this moment, we can assume that everyone is moving forward in a constant speed. ACMers love algorithms, so they want to know not only the result but also who may be in the leading position. Now we know all athletes' position and speed at a specific moment. The problem is, starting from this moment, how many athletes may be the leader. Please notice that there's no leader if two or more athletes are at the leading position at the same time. No two athletes may have the same speed.

Input

The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. The first line of each test case consists of an integer N, indicating the number of athletes. Each of the following N lines consists of two integers: p, v, indicating an athlete's position and speed.

Technical Specification

1. T ≤ 20
2. 0 < N ≤ 50000
3. 0 < p, v ≤ 2000,000,000
4. An athlete's position is the distant between him/her and the start line.
5. The Marathon is so long that you can assume there's no finishline.

Output

For each test case, output the number of possible leaders on a separate line.

Sample Input

1
3
1 1
2 3
3 2

Sample Output

2

 

 

 

 

题解

这题可以明显做一下半平面交

但是有一个做法比较机智,避免了大码量的计算几何,所以要讲一下

我们做半平面交用的是s-t图

有一个明显的性质:一个人被超过了之后就不会再反超了

我们尝试直接用v-p图,把一个人当作一个点

那么两点之间的斜率就是(vx-vy)/(px-py),恰好是相遇时间的倒数1/t   (太巧妙了)(但应该是老套路了吧。。。)

考虑按p,v分别为第一关键字和第二关键字来进行从大到小排序

很明显,当一个人的位置靠后,速度又比较慢的话,就永远出不了头   (好现实啊。。。)

还有一些人,他们有能力超过目前跑在最前面的人,但是它们的速度不够快,在出头之前被别人超过了,也不能统计(好惨…)

这两种情况我们可以通过一个类似斜率优化的单调栈来处理

然后就A了

代码:(不知道为什么,这道题被放在了随机化作业里。。。哦,原来是题型随机的作业,还有道网络流也被放了进来。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50005
#define LL long long
struct node{
	int x,v;
	bool operator <(const node &t)const{return x>t.x||(x==t.x&&v>t.v);}
}a[N];
int stk[N],top;
bool check(node x,node y,node z)
{
	//(y.x-x.x,y.y-x.y)X(z.x-x.x,z.y-x.y);
	if(1ll*(y.x-x.x)*(z.v-x.v)<=1ll*(y.v-x.v)*(z.x-x.x))
		return 1;
	return 0;
}
int main()
{
	int T,n,i,mx;
	scanf("%d",&T);
	while(T--){
		top=0;
		scanf("%d",&n);
		for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].v);
		sort(a+1,a+n+1);
		mx=a[1].v;stk[++top]=1;
		for(i=2;i<=n;i++){
			if(a[i].v<mx)continue;
			mx=a[i].v;
			while(top>1&&check(a[stk[top-1]],a[stk[top]],a[i]))
				top--;
			stk[++top]=i;
		}
		printf("%d\n",top);
	}
}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值