zoukankan      html  css  js  c++  java
  • P1169 [ZJOI2007]棋盘制作

    题目描述

    国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。

    而我们的主人公小Q,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则。

    小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。

    不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。

    于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?

    输入输出格式

    输入格式:

    包含两个整数N和M,分别表示矩形纸片的长和宽。接下来的N行包含一个N * M的01矩阵,表示这张矩形纸片的颜色(0表示白色,1表示黑色)。

    输出格式:

    包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。

    输入输出样例

    输入样例#1:
    3 3
    1 0 1
    0 1 0
    1 0 0
    
    输出样例#1:
    4
    6
    

    说明

    对于20%的数据,N, M ≤ 80

    对于40%的数据,N, M ≤ 400

    对于100%的数据,N, M ≤ 2000

    这道题目有两问,第一问的难度大约是普及

            第二问大约是省选-

    首先我们考虑读入,我们a[i][j]^=(i^j)&1;

    这样我们就把题目转换成了求最大相同值的正方形&&矩形问题

    1.对于正方形

    1 dps[i][j]=min
    2      (
    3          min(dps[i-1][j-1],dps[i][j-1]),
    4        min(dps[i-1][j-1],dps[i-1][j])    
    5      )+1;

    前提条件:

    1 a[i][j]==a[i][j-1]&&a[i][j]==a[i-1][j-1]&&a[i][j]==a[i-1][j]

    2.对于矩形

    我们用dpr1表示在每一个点处,向上枚举相同的值所能到达的最长长度

       dpr2表示在每一个点处,向下枚举相同的值所能到达的最长长度

      (悬线算法)

    然后我们可以暴力枚举行和列,

    对于每一列,dpr1和dpr2必须每次都取最小值(保证相同颜色)

    答案的更新:

     1 ans2=max(ans2,(j-maxlong+1)*(maxup+maxdown-1)); 

    用当前的列减去在它之前的‘最后一个不同的值+1’(也就是maxlong)* 最大的上下边界

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 const int MAXN=2001;
      9 int a[MAXN][MAXN];
     10 int read(int & n)
     11 {
     12     int flag=0,x=0;char c='/';
     13     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
     14     while(c>='0'&&c<='9')x=x*10+(c-48),c=getchar();
     15     if(flag)n=-x;else n=x;
     16 }
     17 int n,m;
     18 int dps[MAXN][MAXN];
     19 int dpr1[MAXN][MAXN];
     20 int dpr2[MAXN][MAXN];
     21 int ans1,ans2;
     22 void square()
     23 {
     24     for(int i=0;i<n;i++)
     25         for(int j=0;j<m;j++)
     26             dps[i][j]=1;        
     27     
     28     for(int i=0;i<n;i++)
     29         for(int j=0;j<m;j++)
     30         {
     31             if(a[i][j]==a[i][j-1]&&a[i][j]==a[i-1][j-1]&&a[i][j]==a[i-1][j])
     32             {
     33                 dps[i][j]=min
     34                          (
     35                           min(dps[i-1][j-1],dps[i][j-1]),
     36                           min(dps[i-1][j-1],dps[i-1][j])    
     37                          )+1;          
     38                 ans1=max(dps[i][j],ans1);
     39             }
     40         }
     41     printf("%d
    ",ans1*ans1);
     42 }
     43 void print()
     44 {
     45     for(int i=0;i<n;i++)
     46     {
     47         for(int j=0;j<m;j++)
     48         {
     49             cout<<a[i][j]<<" ";
     50         }
     51         cout<<endl;
     52     }
     53     cout<<"*************************"<<endl;
     54     for(int i=0;i<n;i++)
     55     {
     56         for(int j=0;j<m;j++)
     57         {
     58             cout<<dpr1[i][j]<<" ";
     59         }
     60         cout<<endl;
     61     }
     62     cout<<"*************************"<<endl;
     63     for(int i=0;i<n;i++)
     64     {
     65         for(int j=0;j<m;j++)
     66         {
     67             cout<<dpr2[i][j]<<" ";
     68         }
     69         cout<<endl;
     70     }
     71     cout<<"*************************"<<endl;
     72 }
     73 void rectangle()
     74 {
     75     for(int i=0;i<n;i++)
     76         for(int j=0;j<m;j++)
     77             dpr1[i][j]=dpr2[i][j]=1;
     78     
     79     for(int i=1;i<n;i++)
     80         for(int j=0;j<m;j++)
     81         if(a[i][j]==a[i-1][j])
     82             dpr1[i][j]=max(dpr1[i][j],dpr1[i-1][j]+1);
     83     
     84     for(int i=n-2;i>=0;i--)
     85         for(int j=0;j<m;j++)
     86         if(a[i][j]==a[i+1][j])
     87             dpr2[i][j]=max(dpr2[i][j],dpr2[i+1][j]+1);
     88     
     89     ans2=1;
     90         
     91     //print();
     92     
     93     for(int i=0;i<n;i++)
     94     {
     95         int maxup=dpr1[i][0];
     96         int maxdown=dpr2[i][0];
     97         int maxlong=0;
     98         for(int j=0;j<m;j++)
     99         {
    100             ans2=max(ans2,(j-maxlong+1)*(maxup+maxdown-1));
    101             if(j==m-1)
    102             break;
    103             if(a[i][j]!=a[i][j+1])
    104             {
    105                 maxlong=j+1;
    106                 maxup=dpr1[i][j+1];
    107                 maxdown=dpr2[i][j+1];
    108             }
    109             else
    110             {
    111                 maxup=min(maxup,dpr1[i][j+1]);
    112                 maxdown=min(maxdown,dpr2[i][j+1]);
    113             }
    114         }
    115     }
    116     
    117     printf("%d",ans2);
    118 }
    119 int main()
    120 {
    121     //freopen("makechess.in","r",stdin);
    122     //freopen("makechess.out","w",stdout);
    123     
    124     
    125     read(n);read(m);
    126     for(int i=0;i<n;i++)
    127         for(int j=0;j<m;j++)
    128         {
    129             read(a[i][j]);
    130             a[i][j]^=(i^j)&1;
    131         }
    132         
    133     square();
    134     rectangle();
    135     return 0;
    136 }
  • 相关阅读:
    iOS6和iOS7代码的适配(3)——坐标适配
    iOS6和iOS7代码的适配(2)——status bar
    iOS6和iOS7代码的适配(1)
    深入Blocks分析
    文字溢出加省略号
    点击图表每一部分触发某事件
    图表添加红线
    比较月份是否存在封装数据
    云上示范区项目总结
    页面之间通过地址栏传参
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6905174.html
Copyright © 2011-2022 走看看