zoukankan      html  css  js  c++  java
  • CF480E Parking Lot

    Description

    Petya's been bored at work and he is killing the time by watching the parking lot at the office. The parking lot looks from above like an $n imes m$ table (a cell of the table corresponds to a single parking spot). Some spots in the parking lot are taken, others are empty.

    Petya watches cars riding into the parking lot one by one. After a car settles down at the parking spot, Petya amuzes himself by counting what maximum square of empty spots (i.e. a square subtable) can be seen on the parking lot if we look at it from above. Also, he takes notes of the square's size (side length) in his notebook.

    You task is: given the state of the parking lot at the initial moment of time and the information about where the arriving cars park, restore what Petya wrote in his notebook. It is midday, so nobody leaves the lot.

    Solution

    考虑倒序做,在倒序视角下,答案递增

    所有修改完成后的答案可以DP跑出来,也可以用单调队列:

    对于每一行跑单调队列,维护每个点向上和向下最长的空位长度,从左向右扫正方形的右边线位置,单调队列维护左边线位置,时间复杂度同样是$O(n^2)$

    对于之后的每一次修改,只需要在修改的那一行上跑单调队列,并维护修改的那一列的向上向下最长长度

    写起来很烦

    #include<iostream>
    #include<cstdio>
    #include<deque>
    using namespace std;
    int n,m,q,x[2005],y[2005],up[2005][2005],down[2005][2005],ans,f[2005];
    bool map[2005][2005];
    deque<int>u,d;
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    bool check(int i,int k)
    {
        u.clear(),d.clear();
        for(int j=1;j<=m;j++)
        {
            while(u.size()&&j-u.front()>=k) u.pop_front();
            while(d.size()&&j-d.front()>=k) d.pop_front();
            while(u.size()&&up[i][j]<=up[i][u.back()]) u.pop_back();
            while(d.size()&&down[i][j]<=down[i][d.back()]) d.pop_back();
            u.push_back(j),d.push_back(j);
            if(j>=k&&up[i][u.front()]+down[i][d.front()]-1>=k) return true;
        }
        return false;
    }
    void solve(int i)
    {
        int temp=0;
        for(int j=1;j<=n;j++) temp=map[j][i]?temp:j,up[j][i]=j-temp;
        temp=n+1;
        for(int j=n;j;j--) temp=map[j][i]?temp:j,down[j][i]=temp-j;
    }
    int main()
    {
        n=read(),m=read(),q=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++) map[i][j]=(getchar()=='.');
            getchar();
        }
        for(int i=1;i<=q;i++) x[i]=read(),y[i]=read(),map[x[i]][y[i]]=false;
        for(int i=1;i<=m;i++) solve(i);
        for(int i=1;i<=n;i++) for(int j=ans+1;;j++)
            if(!check(i,j))
            {
                ans=j-1;break;
            }
        f[q]=ans;
        for(int i=q;i;i--)
        {
            map[x[i]][y[i]]=true,solve(y[i]);
            for(int j=ans+1;;j++)
                if(!check(x[i],j))
                {
                    ans=j-1;break;
                }
            f[i-1]=ans;
        }
        for(int i=1;i<=q;i++) printf("%d
    ",f[i]);
        return 0;
    }
    Parking Lot
  • 相关阅读:
    在VMWare虚拟机下的ubuntu中Samba服务的安装
    Shell表达式,如${file##*/}
    如何从官网下载QT
    SATA命令之security
    Clip
    JS判断是否在微信浏览器打开
    微信小程序请求数据报错: 如若已在管理后台更新域名配置,请刷新项目配置后重新编译项目,操作路径:“详情-域名信息”
    typeof()和instanceof的用法区别
    javascrip 对数组的操作方法
    微信小程序 修改数据,并动态渲染页面;修改数组;
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14070834.html
Copyright © 2011-2022 走看看