zoukankan      html  css  js  c++  java
  • [luogu]P1168:[ZJOI2007]棋盘制作

    原题链接

    P1169 [ZJOI2007]棋盘制作

    分析

    题目有两个问题,一个是要求输出最大的正方形面积,另一个为输出最大的矩形面积。
    而且问题要求图必须是黑白相间的,我们需要对图进行预处理。
    有两种情况。

    1. 黑格横纵坐标奇偶性相同,白格不同。
    2. 白格横纵坐标奇偶性相同,黑格不同。

    这样我们就可以处理黑白相间的问题了。我们在跑完第一种之后把图反色,重新跑一遍。
    先考虑如何求最大正方形。
    f[i][j]表示以i,j为右下点的正方形的最大边长。
    状态转移方程很显然,我们要从i,j向四周拓展,而最早被卡住的点应该就是他们的最小值
    所以
    f[i][j]=min{f[i-1][j],f[i][j-1],f[i-1][j-1]}+1;

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int Maxn=2009;
    int n,m,g[Maxn][Maxn],st[Maxn],t=1,f[Maxn][Maxn];
    int pos[Maxn],maxn=0,l[Maxn],r[Maxn],ans=0;
    void work(){
    	memset(g,0,sizeof(g));
    	for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(!f[i][j])continue;
                else g[i][j]=f[i][j]+g[i-1][j];
            }
        }
        for(int i=1;i<=n;i++){
            memset(l,0,sizeof(l));t=1;
            st[t]=g[i][1];pos[t]=1;l[1]=1;
            for(int j=2;j<=m;j++){
                while(t>0&&st[t]>=g[i][j])t--;
                st[++t]=g[i][j];
                pos[t]=j;
                l[j]=pos[t]-((t>1)?(pos[t-1]):0);
                
            }
            memset(r,0,sizeof(r));t=1;
            st[t]=g[i][m];pos[t]=m;r[m]=1;
            for(int j=m-1;j>=1;j--){
                while(t>0&&st[t]>=g[i][j])t--;
                st[++t]=g[i][j];
                pos[t]=j;
                r[j]=((t>1)?(pos[t-1]):m+1)-pos[t];
            }
            for(int j=1;j<=m;j++)
                maxn=max(maxn,g[i][j]*(r[j]+l[j]-1));
    	}
    }
    int main()
    {
    	//freopen("data.in","r",stdin);
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++){
    			cin>>f[i][j];
    			if ((i & 1) == (j & 1) && f[i][j] || (i & 1) != (j & 1) && !f[i][j])
    				f[i][j]=1;
    			else f[i][j]=0;
    		}
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    		g[i][j]=(min(min(g[i-1][j],g[i][j-1]),g[i-1][j-1])+1)*f[i][j],
    		ans=max(ans,g[i][j]);
    	work();
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			f[i][j]=1-f[i][j];
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    		g[i][j]=(min(min(g[i-1][j],g[i][j-1]),g[i-1][j-1])+1)*f[i][j],
    		ans=max(ans,g[i][j]);
    	work();
    	printf("%d
    %d
    ",ans*ans,maxn);
    	return 0;
    }
    
    
    
  • 相关阅读:
    收藏好博客
    iOS设备的重力感应
    局域网内通过UDP协议进行传输接受数据——AsyncUdpSocket
    定时器NSTimer的用法
    线程数:5,ramp-up:1,循环::10 和 线程数:10,ramp-up:10,循环数:1,这两种情况有没有区别?
    什么是性能测试?
    JMeter 之 XPath提取器
    DNS--安装&&配置文件
    DNS--简介&&解析过程
    Tomcat--隐藏版本号
  • 原文地址:https://www.cnblogs.com/onglublog/p/9859742.html
Copyright © 2011-2022 走看看