HDU.6759 Leading Robots(单调栈)

HDU.6759Leading Robots(单调栈)

思路:单调栈。

考虑:对机器人进行排序,按照加速度从小到大,加速相同,位置从小到大排序,保证后面下标的机器人能超过前面下标的机器人或者位置相同。

然后我们前往后开始遍历,如果当前机器人比栈顶机器人初始位置大,说明该机器人始终在栈顶的机器人前面, 即栈顶的机器人不可能是第一,所以弹出栈顶,若当前栈中有至少两个机器人,我们则需比较 a , b , i a,b,i , b , a b,a 分别为栈顶的元素,栈顶的前一个元素。

若机器人 i i 超过 b b 的时间小于等于 b b 超过 a a 的时间,说明 b b 在超过 a a 之前, c c 永远在 b b 前面,即 b b 不可能得第一,所以 b b 出栈,然后 a , i a,i 同理继续比较。

另外需要注意的是特判一下完全相同的机器人是不可能得第一,因为他们位置始终相同,第一需要超越所有其他机器人。

时间复杂度: O ( n l o g n ) O(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
map<PII,int>mp;
int stk[N],n,t,top,ans;
PII a[N];
bool cmp(PII a,PII b){
	return a.fi==b.fi?a.se<b.se:a.fi<b.fi;
} 
bool check(PII a,PII b,PII c){
	return 1LL*(b.se-c.se)*(b.fi-a.fi)-1LL*(c.fi-b.fi)*(a.se-b.se)<=0;//这里有可能爆int 
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);mp.clear(),top=0;
		for(int i=1;i<=n;i++) scanf("%d%d",&a[i].se,&a[i].fi),mp[a[i]]++;
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++){
			while((top>0&&a[stk[top]].se<=a[i].se)||(top>1&&check(a[stk[top-1]],a[stk[top]],a[i]))) top--;
			stk[++top]=i;
		} ans=top;
		for(int i=top;i;i--){
			if(mp[a[stk[i]]]>1) ans--;
		}
		printf("%d\n",ans);
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107558366