Description
Those lines divide the plane into four quadrants. The quadrant containing points with arbitrarily large positive coordinates is the top-right quadrant.
The players score according to the number of brownie points in the quadrants. If a brownie point is crossed by a line, it doesn't count. Stan gets a point for each (uncrossed) brownie point in the top-right and bottom-left quadrants. Ollie gets a point for each (uncrossed) brownie point in the top-left and bottom-right quadrants.
Stan and Ollie each try to maximize his own score. When Stan plays, he considers the responses, and chooses a line which maximizes his smallest-possible score.
Input
Output
Sample Input
11 3 2 3 3 3 4 3 6 2 -2 1 -3 0 0 -3 -3 -3 -2 -3 -4 3 -7 0
Sample Output
Stan: 7; Ollie: 2 3;
一个平面有一些点,stan先竖着画一条线(必须经过一个点),ollie横着画一条线(必须经过stan画的线上的一个点),stan得分是一三象限的点数,ollie得分是二四象限的点数,在线上的不算。ollie要在自己得分最高的情况下让stan得分最少,输出stan得最低分最高的情况下的最低分,和stan得到这个分数时ollie的所有可能得分。
参考了cxlove大神的,用两个树状数组表示竖线的左边和右边,对y离散化。一开始把所有点都加到右边的树状数组,竖线从左到右扫过去,每次把在竖线上的点从右边删除,算出在这条竖线上每个点画横线的情况a和b,更新答案:如果b比当前的ollie更大,把a和b都赋值成当前值,如果b等于当前ollie值,就把stan更新到min(stan,a)。这条线所有点更新完后的stan如果小于当前答案就把存ollie的vector清空,如果等于当前答案的话就把ollie存到vector里。
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<algorithm>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define MAXN 200010
#define MAXM 2000010
#define MAXNODE MAXN*4
#define MOD 999983
typedef long long LL;
using namespace std;
int N,l[MAXN],r[MAXN],y[MAXN];
vector<int> Ollie;
struct Point{
int x,y;
bool operator < (const Point& a) const{
return x<a.x;
}
}p[MAXN];
int lowbit(int x){
return x&(-x);
}
void update(int *c,int i,int v){
while(i<=N){
c[i]+=v;
i+=lowbit(i);
}
}
int sum(int *c,int i){
int ret=0;
while(i>0){
ret+=c[i];
i-=lowbit(i);
}
return ret;
}
int main(){
freopen("in.txt","r",stdin);
while(scanf("%d",&N)!=EOF&&N){
for(int i=0;i<N;i++){
scanf("%d%d",&p[i].x,&p[i].y);
y[i]=p[i].y;
}
sort(y,y+N);
sort(p,p+N);
int n=unique(y,y+N)-y;
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(int i=0;i<N;i++) update(r,lower_bound(y,y+n,p[i].y)-y+1,1);
int Stan=-1,e;
Ollie.clear();
for(int i=0;i<N;i++) if(!i||p[i].x!=p[i-1].x){
update(r,lower_bound(y,y+n,p[i].y)-y+1,-1);
e=i;
for(int j=i+1;j<N&&p[j].x==p[j-1].x;j++){
update(r,lower_bound(y,y+n,p[j].y)-y+1,-1);
e=j;
}
int stan=INF,ollie=-1;
for(int j=i;j<=e;j++){
int pos=lower_bound(y,y+n,p[j].y)-y+1;
int a=sum(l,pos-1)+sum(r,n)-sum(r,pos),b=sum(r,pos-1)+sum(l,n)-sum(l,pos);
if(b==ollie) stan=min(stan,a);
else if(b>ollie){
stan=a;
ollie=b;
}
}
if(stan>Stan){
Stan=stan;
Ollie.clear();
}
if(stan==Stan) Ollie.push_back(ollie);
for(int j=i;j<=e;j++) update(l,lower_bound(y,y+n,p[j].y)-y+1,1);
}
printf("Stan: %d; Ollie:",Stan);
sort(Ollie.begin(),Ollie.end());
n=unique(Ollie.begin(),Ollie.end())-Ollie.begin();
for(int i=0;i<n;i++) printf(" %d",Ollie[i]);
puts(";");
}
return 0;
}
5535



被折叠的 条评论
为什么被折叠?



