bzoj1007

一开始看到这道题只能想到n^2暴力

不知道如何下手

实际上,我们要找到一种筛选的办法,这种筛选方法要在某种情况(顺序)下通用,

于是我们就可以按A值从大到小排序,用一个栈来维护后面加入的边

所以当一条边不合法,那它一定会被后来的边给弹出栈,具体可以通过求点的坐标来得知

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
struct mod{double A,B;int wei;};
mod q[50005];
bool cmp(mod x,mod y)
{
 if (x.A>y.A)return true;
 if (x.A<y.A)return false;
 return x.B<y.B;
}
bool v[50005];
int t[50005],tp=0;
int main()
{
 int n;
 scanf("%d",&n);
 for (int i=1;i<=n;i++)
 {
  scanf("%lf%lf",&q[i].A,&q[i].B);
  q[i].wei=i;
 }
 sort(q+1,q+n+1,cmp);
 /*for (int i=1;i<=n;i++)
 printf("i:%d %lf %lf\n",i,q[i].A,q[i].B);*/
 tp++;
 t[1]=1;
 for (int i=2;i<=n;i++)
 {
  while(tp>1)
  {
   int o=t[tp];
   double KK=q[i].A-q[o].A;
   if (KK==0.0){tp--;continue;}
   double BB=q[o].B-q[i].B;
   double X2=BB/KK;
   KK=q[i].A-q[t[tp-1]].A;
   BB=q[t[tp-1]].B-q[i].B;
   double X1=BB/KK;
   if (X1<=X2)tp--;
   else break;
  }
  tp++;
  t[tp]=i;
 }
 memset(v,false,sizeof(v));
 for (int i=1;i<=tp;i++)
  v[q[t[i]].wei]=true;
  bool tf=false;
 for (int i=1;i<=n;i++)
 if (v[i])
 {
  if (tf)printf(" ");
  else tf=true;
  printf("%d",i);
 }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值