您的位置:首页 > 运维架构

2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) B - Bribing Eve

2017-07-19 21:08 531 查看

地址:http://codeforces.com/gym/101174/attachments

题目:pdf,略

 

思路:

  把每个人的(x1,x2)抽象成点(xi,yi).

  当1号比i号排名高时有==>a(x1-xi)+b(y1-yi)>=0

  把(x1-xi,y1-yi)看着向量,(a,b)看做向量。则和(a,b)夹角在90度内的向量个数就是不如1号点优的个数。

  所以要使1号得到最高排名就是使和(a,b)夹角在90度内(包括90度)的向量个数最大。

  所以要使1号得到最低排名就是使和(a,b)夹角在90度内(不包括90度)的向量个数最小。

  注意特判掉xi==x1 && yi==y1的点,以及(a,b)只能在第一象限内。

  求解最高or低排名的过程:

    把所有向量求个极角,然后极角排序。扫一遍有用的可能的(a,b)向量,中间利用two point的方法维护答案。

#include <bits/stdc++.h>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int,int> PII;
const double eps=1e-8;
const double pi=acos(-1.0);
const int K=1e5+7;
const int mod=1e9+7;

double angle[K],tmp[K];
int n,m,ansa,ansb=K;
int sgn(double ta,double tb)
{
if(fabs(ta-tb)<eps) return 0;
return ta<tb?-1:1;
}
int sc(void)
{
int l=1,r=0;
double nt1,nt2;
for(int i=0;i<m;i++)
{
int tl=l,tr=r;
nt1=tmp[i]+pi/2.0;
nt2=tmp[i]-pi/2.0;

while(r<n-1 && sgn(angle[r+1],nt1)<=0) r++;
while(l<=r && sgn(angle[l],nt2)<0) l++;
while(tr && sgn(angle[tr],nt1)==0) tr--;
while(tr<n-1 && sgn(angle[tr+1],nt1)<0) tr++;
while(tl<=tr && sgn(angle[tl],nt2)<=0) tl++;
ansa=max(ansa,r-l+1);
ansb=min(ansb,tr-tl+1);
tr++;
}
}
int main(void)
{
int sx,sy,tn=1,same=0;
scanf("%d",&n);
scanf("%d%d",&sx,&sy);
for(int i=2,x,y;i<=n;i++)
{
scanf("%d%d",&x,&y);
if(x==sx && y==sy) {same++;continue;}
angle[tn]=atan2(sy-y,sx-x);
if(sgn(angle[tn],pi/2.0)>=0 && sgn(angle[tn],pi)<=0)
tmp[m++]=angle[tn]-pi/2.0;
else if(sgn(angle[tn],-pi/2.0)>=0 && sgn(angle[tn],0.0)<=0)
tmp[m++]=angle[tn]+pi/2.0;
tn++;
}
n=tn;
sort(angle+1,angle+tn);
sort(tmp,tmp+m);
sc();
printf("%d %d\n",n-ansa,n-ansb+same);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐