• 51nod 1562 玻璃切割


     

    1562 玻璃切割

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1562

    题目来源: CodeForces
    基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题

    现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。

    切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。

    现在想知道每次切割之后面积最大的一块玻璃是多少。

    样例解释:


    对于第四次切割,下面四块玻璃的面积是一样大的。都是2。

    Input
    单组测试数据。
    第一行有三个整数 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在横向上长w 毫米,纵向上长h 毫米,接下来有n次的切割。
    接下来有n行输入,每一行描述一次切割。
    输入的格式是H y 或 V x。
    H y表示横向切割,切割线距离下边缘y毫米(1≤y≤h-1)。
    V x表示纵向切割,切割线距离左边缘x毫米(1≤x≤w-1)。
    输入保证不会有两次切割是一样的。
    Output
    对于每一次切割,输出所有玻璃中面积最大的是多少。
    Input示例
    样例输入1
    4 3 4
    H 2
    V 2
    V 3
    V 1
    Output示例
    样例输出1
    8
    4
    4
    2
    对于每一行,记录它上一行和下一行的位置,以及它距离上一行的长度,列同理
    由于所有的线都是直线,所以最大面积=最大行间距*最大列间距
    为了减小复杂度,离线做,把最终的形态先弄出来,找到最大值,然后按相反的顺序删边,容易知道,如果删边会产生更大的玻璃,这块玻璃一定以删去的边为边,于是直接更新不需要其他操作。
    最后别忘了用long long
    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define maxn 200010
    long long w,h,n,ans[maxn];
    bool X[maxn],Y[maxn];
    struct node{
        char ch[3];long long x;
    }op[maxn];
    struct Node{
        long long pre,nxt,v;
    }hang[maxn],lie[maxn];
    int main(){
        freopen("cola.txt","r",stdin);
        scanf("%lld%lld%lld",&w,&h,&n);
        X[0]=X[h]=Y[0]=Y[w]=1;
        for(long long i=1;i<=n;i++){
            scanf("%s%d",op[i].ch,&op[i].x);
            if(op[i].ch[0]=='H')X[op[i].x]=1;
            if(op[i].ch[0]=='V')Y[op[i].x]=1;
        }
        ans[0]=w*h;
        long long dx=0,dy=0;
        for(long long i=0,p=0;i<=w;i++){
            if(Y[i]==1)
            lie[i].pre=p,lie[p].nxt=i,lie[i].v=i-p,dy=max(dy,i-p),p=i;
        }
        lie[w].nxt=w;
        for(long long i=0,p=0;i<=h;i++){
            if(X[i]==1)
            hang[i].pre=p,hang[p].nxt=i,hang[i].v=i-p,dx=max(dx,i-p),p=i;
        }
        hang[h].nxt=h;
        ans[n]=dx*dy;
        for(long long i=n;i>=2;i--){
            if(op[i].ch[0]=='H'){
                long long u=op[i].x;
                hang[hang[u].nxt].v+=hang[u].v;
                hang[hang[u].pre].nxt=hang[u].nxt;
                hang[hang[u].nxt].pre=hang[u].pre;
                dx=max(dx,hang[hang[u].nxt].v);
            }
            else{
                long long u=op[i].x;
                lie[lie[u].nxt].v+=lie[u].v;
                lie[lie[u].pre].nxt=lie[u].nxt;
                lie[lie[u].nxt].pre=lie[u].pre;
                dy=max(dy,lie[lie[u].nxt].v);
            }
            ans[i-1]=dx*dy;
        }
        for(long long i=1;i<=n;i++){
            printf("%lld\n",ans[i]);
        }
    }
  • 相关阅读:
    vim 命令替换重复命令
    Python环境安装
    MySQL 查看show profile
    XSS攻击与CSRF攻击与防御
    HTTPS的原理
    PHP curl的请求步骤
    【论文阅读】HRNet
    【学习笔记】gRPC-python
    【Linux学习笔记】Linux基础
    【Golang学习笔记】入门:结构体、方法与接口
  • 原文地址:https://www.cnblogs.com/thmyl/p/6802952.html
Copyright © 2020-2023  润新知