zoukankan      html  css  js  c++  java
  • [2020多校联考]糖果机器

    Solution

    思路太妙,我想不到

    一个位置的机器人能及时到达另一个位置去接糖果,当且仅当位置之差小于等于时间差,从 (i) 走到 (j) 用符号表示为

    [T_j-T_igeq |S_j-S_i| ]

    把绝对值拆掉

    [egin{cases} T_j-T_igeq S_j-S_i\ T_j-T_igeq S_i-S_j end{cases}]

    再移项,把 (i)(j) 分别移到其中一边

    [egin{cases} T_j-S_jgeq T_i-S_i\ T_j+S_jgeq T_i+S_i end{cases}]

    将两边看成一个整体,将 (T_x-S_x) 当成横坐标,将 (T_x+S_x) 当成纵坐标。若能从 (i) 走到 (j),那么点 ((T_i-S_i,T_i+S_i)) 一定在以点 ((T_j-S_j,T_j+S_j)) 为右上角的矩形内。所以就转换为了二维偏序。先按第横坐标为第一关键字纵坐标为第二关键字排序之后,一个机器人能接住的糖就是点纵坐标单调不降的一个子序列。使机器人个数最小化,实际上是用最少的没有交集的单调不降子序列来覆盖原序列。见导弹拦截

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 100007
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    struct Node{
        int pos,t;
        int x,y;
        bool operator <(const Node X) const {
            if(x==X.x) return y<X.y;
            return x<X.x;
        }
    }a[N];
    
    int n,top=0,tag[N],sta[N];
    int main(){
        freopen("candy.in","r",stdin);
        freopen("candy.out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++){
            a[i].pos=read(),a[i].t=read();
            a[i].x=a[i].t+a[i].pos,a[i].y=a[i].t-a[i].pos;
        }
        sort(a+1,a+1+n);
        sta[++top]=a[1].y,tag[1]=1;
        for(int i=2;i<=n;i++){
            if(sta[top]>a[i].y){
                sta[++top]=a[i].y;
                tag[i]=top;
            }else{
                int l=1,r=top,ret=0;
                while(l<=r){
                    int mid=(l+r)>>1;
                    if(sta[mid]<=a[i].y){
                        r=mid-1;
                        ret=mid;
                    }else l=mid+1;
                }
                if(!ret) ret=1;
                tag[i]=ret,sta[ret]=a[i].y;
            }
        }
        printf("%d
    ",top);
        for(int i=1;i<=n;i++)
            printf("%d %d %d
    ",a[i].pos,a[i].t,tag[i]);
    }
    /*
    5
    1 1
    2 3
    1 5
    3 4
    2 6
    */
    

    Tips

    至于纵坐标为什么也要升序,可以考虑在横坐标相等的情况下,纵坐标小的可以转移到纵坐标大的,反之不行,所以升序更优。

  • 相关阅读:
    人月神话阅读笔记(三)
    MongoDB设置用户名以及密码
    pdf.js使用总结#如何在网页读取并显示PDF格式文档
    Python中eval函数的作用
    寒假学习笔记(13)
    寒假学习笔记(12)
    寒假学习笔记(11)
    寒假学习笔记(10)
    寒假学习笔记(9)
    寒假学习笔记(8)
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14063747.html
Copyright © 2011-2022 走看看