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;
    }
    
    
    
  • 相关阅读:
    百度搜索API v3版本与soap
    Yii整合ZF2及soap实例
    Getting started writing ZF2 modules
    js写出php中的函数系列
    一些有用的命令
    a标签至于flash之上的时候,IE浏览器无法点击连接的问题
    js问题集锦
    php常用函数集锦[备份用的]
    用过的一些js函数[备份用的]
    ELK
  • 原文地址:https://www.cnblogs.com/onglublog/p/9859742.html
Copyright © 2011-2022 走看看