Poj 2464 Brownie Points II(平面两条垂直的先划分成四个象限,一三象限和二四象限各有多少个)

本文针对Poj2464题目中的游戏策略进行解析,通过维护线段树来快速计算不同划分下玩家的得分情况。具体地,算法以枚举的方式确定分界线,利用线段树维护每个分界线左右两侧的数据,实现高效计算得分的目的。

传送门:Poj 2464 Brownie Points II


题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个stan之前画过的点。这时候平面就被分割成了四块,两个人这时候会有一个得分,stan的得分是平面上第1、3象限内的点的个数,ollie的得分是平面上第2、4象限内的点的个数,在统计的时候在所画线上的点都不计算在内。求最终stan使得自己的最差得分最高,并且输出此时ollie的得分。
(N<=2e5)


思路:
我们可以枚举分界线,分界线左右两边各维护一个线段树
枚举分界线上的每个点的y值,那么1,3象限对应的y值也就能确定了
那么就可以确定在1,3象限的点的个数,对应的2,4象限用vector存起来


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define INF 0x3f3f3f3f
const int N=2e5+10;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct Point{
    int x,y;
}a[N];
int t[N];
int sumv[2][N*4],Count[N],x[N];
vector<int>tmp;

bool cmp(Point u,Point v){
    if(u.x!=v.x)
        return u.x<v.x;
    return u.y<v.y;
}

int pos,d;

void pushup(int rt,int flag){
    sumv[flag][rt]=sumv[flag][rt<<1]+sumv[flag][rt<<1|1];
}

void update(int l,int r,int rt,int flag){
    if(l==r){
        sumv[flag][rt]+=d;
        return ;
    }
    int m=(l+r)>>1;
    if(pos<=m)  update(lson,flag);
    else    update(rson,flag);
    pushup(rt,flag);
}

int L,R;

int query(int l,int r,int rt,int flag){
    if(L<=l&&R>=r)
        return sumv[flag][rt];
    int m=l+r>>1,Ans=0;
    if(L<=m)    Ans+=query(lson,flag);
    if(R>m)     Ans+=query(rson,flag);
    return Ans;
}

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        if(n==0)    break;
        tmp.clear();
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            t[i]=a[i].y,x[i]=a[i].x;
        }
        sort(a+1,a+n+1,cmp);
        sort(t+1,t+n+1);
        sort(x+1,x+n+1);
        int m=unique(t+1,t+n+1)-t-1,mm=unique(x+1,x+n+1)-x-1;
        memset(sumv,0,sizeof(sumv));
        memset(Count,0,sizeof(Count));  //每一行有多少个
        for(int i=1;i<=n;i++){  //将点全部插入到第二颗
            pos=lower_bound(t+1,t+m+1,a[i].y)-t,d=1;
            Count[pos]++;
            update(1,n,1,1);
        }
        int st=1,Stan=0;
        for(int i=1;i<=mm;i++){
            int ed=st;
            while(st<=n&&a[st].x==x[i]){    //同一列一起处理
                pos=lower_bound(t+1,t+m+1,a[st].y)-t,d=-1;
                update(1,n,1,1);
                ++st;
            }
            int Ollie=-1,stan=-1;
            for(int j=ed;j<st;j++){ //枚举取哪一个点
                int num=lower_bound(t+1,t+m+1,a[j].y)-t,Ans=0;
                while(j-1>=ed&&a[j].y==a[j-1].y){

                }
                L=num+1,R=m;
                if(L<=R)    Ans+=query(1,n,1,1);
                L=1,R=num-1;
                if(L<=R)    Ans+=query(1,n,1,0);
                if(n-(st-ed)-Count[num]+1-Ans>Ollie)
                    stan=Ans,Ollie=n-(st-ed)-Count[num]+1-Ans;
                else  if(n-(st-ed)-Count[num]+1-Ans==Ollie)
                    stan=min(stan,Ans);
            }
            if(stan>Stan){
                tmp.clear();
                Stan=stan;
            }
            if(stan==Stan)
                tmp.push_back(Ollie);
            for(int j=ed;j<st;j++){
                int num=lower_bound(t+1,t+m+1,a[j].y)-t;
                pos=num,d=1;
                update(1,n,1,0);
            }
        }
        sort(tmp.begin(),tmp.end());
        vector<int>::iterator iter=unique(tmp.begin(),tmp.end());
        tmp.erase(iter,tmp.end());
        printf("Stan: %d; Ollie:",Stan);
        for(int i=0;i<tmp.size();i++)  printf(" %d",tmp[i]);
        printf(";\n");
    }
    return 0;
}

基于51单片机,实现对直流电机的调速、测速以及正反转控制。项目包含完整的仿真文件、源程序、原理图PCB设计文件,适合学习实践51单片机在电机控制方面的应用。 功能特点 调速控制:通过按键调整PWM占空比,实现电机的速度调节。 测速功能:采用霍尔传感器非接触式测速,实时显示电机转速。 正反转控制:通过按键切换电机的正转反转状态。 LCD显示:使用LCD1602液晶显示屏,显示当前的转速PWM占空比。 硬件组 主控制器:STC89C51/52单片机(与AT89S51/52、AT89C51/52通用)。 测速传感器:霍尔传感器,用于非接触式测速。 显示模块:LCD1602液晶显示屏,显示转速占空比。 电机驱动:采用双H桥电路,控制电机的正反转调速。 软件设计 编程语言:C语言。 开发环境:Keil uVision。 仿真工具:Proteus。 使用说明 液晶屏显示: 第一行显示电机转速(单位:转/分)。 第二行显示PWM占空比(0~100%)。 按键功能: 1键:加速键,短按占空比加1,长按连续加。 2键:减速键,短按占空比减1,长按连续减。 3键:反转切换键,按下后电机反转。 4键:正转切换键,按下后电机正转。 5键:开始暂停键,按一下开始,再按一下暂停。 注意事项 磁铁霍尔元件的距离应保持在2mm左右,过近可能会在电机转动时碰到霍尔元件,过远则可能导致霍尔元件无法检测到磁铁。 资源文件 仿真文件:Proteus仿真文件,用于模拟电机控制系统的运行。 源程序:Keil uVision项目文件,包含完整的C语言源代码。 原理图:电路设计原理图,详细展示了各模块的连接方式。 PCB设计:PCB布局文件,可用于实际电路板的制作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值