HDU.6759Leading Robots(单调栈)
思路:单调栈。
考虑:对机器人进行排序,按照加速度从小到大,加速相同,位置从小到大排序,保证后面下标的机器人能超过前面下标的机器人或者位置相同。
然后我们前往后开始遍历,如果当前机器人比栈顶机器人初始位置大,说明该机器人始终在栈顶的机器人前面, 即栈顶的机器人不可能是第一,所以弹出栈顶,若当前栈中有至少两个机器人,我们则需比较 , 分别为栈顶的元素,栈顶的前一个元素。
若机器人 超过 的时间小于等于 超过 的时间,说明 在超过 之前, 永远在 前面,即 不可能得第一,所以 出栈,然后 同理继续比较。
另外需要注意的是特判一下完全相同的机器人是不可能得第一,因为他们位置始终相同,第一需要超越所有其他机器人。
时间复杂度:
#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;
}