首先特判全部都是A或者全部都是B或者$n=1$的情况。

然后把矩阵四周都填充上A,枚举一个块,分以下情况讨论:

1.在它四周选两个块扩展,此时平方暴力枚举即可。

2.在它四周选定一个方向扩展两步。

3.选择一个角落,斜着扩展一步,再扩展另一步。

时间复杂度$O(n^2)$。

#include<cstdio>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define N 1010
int n,m,i,j,x,y,l,r,f[N][N],ans,t,q[10000][3],cnt;bool a[N][N];char ch[N];
struct P{int x,y,l,r,s;}s[N*N];
inline void up(int b){if(ans<b)ans=b;}
inline void add(int x,int y,int z){
if(x&&x==y)return;
q[++cnt][0]=x,q[cnt][1]=y,q[cnt][2]=z;
}
int main(){
scanf("%d",&n);gets(ch);
if(n==1)return printf("1",ans),0;
rep(i,1,n)for(gets(ch+1),j=1;j<=n;j++)if(ch[j]=='B')a[i][j]=1;
rep(i,1,n)rep(j,1,n)if(a[i][j]&&!f[i][j]){
for(x=i;a[x][j];x++);
for(y=j;a[i][y];y++);
s[++m].x=i,s[m].y=--x,s[m].l=j,s[m].r=--y;
up(s[m].s=(x-i+1)*(y-j+1));
rep(I,i,x)rep(J,j,y)f[I][J]=m;
}
if(ans==n*n)return printf("%d",ans),0;
for(i=n;~i;i--)for(j=n;~j;j--)f[i+1][j+1]=f[i][j];
for(i=1;i<=m;i++)s[i].x++,s[i].y++,s[i].l++,s[i].r++;
n+=2;
ans=2;
rep(i,1,m){
x=s[i].x,y=s[i].y,l=s[i].l,r=s[i].r,cnt=0;
if(x>2)rep(j,l,r){
if(f[x-2][j])add(f[x-2][j],0,0);
else{
t=s[i].s+2+s[f[x-2][j-1]].s+s[f[x-2][j+1]].s;
if(f[x-2][j-1]!=f[x-1][j-1])t+=s[f[x-1][j-1]].s;
if(f[x-2][j+1]!=f[x-1][j+1])t+=s[f[x-1][j+1]].s;
if(x>3)t+=s[f[x-3][j]].s;
up(t);
}
}
if(y+2<=n)rep(j,l,r){
if(f[y+2][j])add(f[y+2][j],0,0);
else{
t=s[i].s+2+s[f[y+2][j-1]].s+s[f[y+2][j+1]].s;
if(f[y+2][j-1]!=f[y+1][j-1])t+=s[f[y+1][j-1]].s;
if(f[y+2][j+1]!=f[y+1][j+1])t+=s[f[y+1][j+1]].s;
if(y+3<=n)t+=s[f[y+3][j]].s;
up(t);
}
}
if(l>2)rep(j,x,y){
if(f[j][l-2])add(f[j][l-2],0,0);
else{
t=s[i].s+2+s[f[j-1][l-2]].s+s[f[j+1][l-2]].s;
if(f[j-1][l-2]!=f[j-1][l-1])t+=s[f[j-1][l-1]].s;
if(f[j+1][l-2]!=f[j+1][l-1])t+=s[f[j+1][l-1]].s;
if(l>3)t+=s[f[j][l-3]].s;
up(t);
}
}
if(r+2<=n)rep(j,x,y){
if(f[j][r+2])add(f[j][r+2],0,0);
else{
t=s[i].s+2+s[f[j-1][r+2]].s+s[f[j+1][r+2]].s;
if(f[j-1][r+2]!=f[j-1][r+1])t+=s[f[j-1][r+1]].s;
if(f[j+1][r+2]!=f[j+1][r+1])t+=s[f[j+1][r+1]].s;
if(r+3<=n)t+=s[f[j][r+3]].s;
up(t);
}
}
if(f[x-1][l-1]){
if(x>2)add(f[x-1][l-1],f[x-2][l],0);
if(l>2)add(f[x-1][l-1],f[x][l-2],0);
}
if(f[y+1][l-1]){
if(y+2<=n)add(f[y+1][l-1],f[y+2][l],0);
if(l>2)add(f[y+1][l-1],f[y][l-2],0);
}
if(f[x-1][r+1]){
if(x>2)add(f[x-1][r+1],f[x-2][r],0);
if(r+2<=n)add(f[x-1][r+1],f[x][r+2],0);
}
if(f[y+1][r+1]){
if(y+2<=n)add(f[y+1][r+1],f[y+2][r],0);
if(r+2<=n)add(f[y+1][r+1],f[y][r+2],0);
}
if(x==y){
if(l>2)add(f[x][l-2],f[x-1][l-1],f[x+1][l-1]);
if(r+2<=n)add(f[x][r+2],f[x-1][r+1],f[x+1][r+1]);
}
if(l==r){
if(x>2)add(f[x-2][l],f[x-1][l-1],f[x-1][l+1]);
if(y+2<=n)add(f[y+2][l],f[y+1][l-1],f[y+1][l+1]);
}
up(s[i].s+2);
rep(j,1,cnt){
up(s[i].s+2+s[q[j][0]].s+s[q[j][1]].s+s[q[j][2]].s);
rep(k,j+1,cnt){
t=s[i].s+2+s[q[j][0]].s+s[q[j][1]].s+s[q[j][2]].s+s[q[k][0]].s+s[q[k][1]].s+s[q[k][2]].s;
if(q[k][0]==q[j][0]||q[k][0]==q[j][1]||q[k][0]==q[j][2])t-=s[q[k][0]].s;
if(q[k][1]==q[j][0]||q[k][1]==q[j][1]||q[k][1]==q[j][2])t-=s[q[k][1]].s;
if(q[k][2]==q[j][0]||q[k][2]==q[j][1]||q[k][2]==q[j][2])t-=s[q[k][2]].s;
up(t);
}
}
if(x>1&&l>1&&!f[x-1][l-1]){
t=s[i].s+2+s[f[x-2][l-1]].s+s[f[x-1][l-2]].s;
if(x==y&&l==r){
if(f[x-1][l-2]!=f[x][l-2])up(t+s[f[x][l-2]].s+s[f[x+1][l-1]].s);else up(t+s[f[x+1][l-1]].s);
if(f[x-2][l-1]!=f[x-2][l])up(t+s[f[x-2][l]].s+s[f[x-1][l+1]].s);else up(t+s[f[x-1][l+1]].s);
}else{
if(f[x-1][l-2]!=f[x][l-2])up(t+s[f[x][l-2]].s);
if(f[x-2][l-1]!=f[x-2][l])up(t+s[f[x-2][l]].s);
}
}
if(x>1&&r<n&&!f[x-1][r+1]){
t=s[i].s+2+s[f[x-2][r+1]].s+s[f[x-1][r+2]].s;
if(x==y&&l==r){
if(f[x-1][r+2]!=f[x][r+2])up(t+s[f[x][r+2]].s+s[f[x+1][l+1]].s);else up(t+s[f[x+1][l+1]].s);
if(f[x-2][r+1]!=f[x-2][r])up(t+s[f[x-2][r]].s+s[f[x-1][l-1]].s);else up(t+s[f[x-1][l-1]].s);
}else{
if(f[x-1][r+2]!=f[x][r+2])up(t+s[f[x][r+2]].s);
if(f[x-2][r+1]!=f[x-2][r])up(t+s[f[x-2][r]].s);
}
}
if(y<n&&l>1&&!f[y+1][l-1]){
t=s[i].s+2+s[f[y+2][l-1]].s+s[f[y+1][l-2]].s;
if(x==y&&l==r){
if(f[y+1][l-2]!=f[y][l-2])up(t+s[f[y][l-2]].s+s[f[x-1][l-1]].s);else up(t+s[f[x-1][l-1]].s);
if(f[y+2][l-1]!=f[y+2][l])up(t+s[f[y+2][l]].s+s[f[x+1][l+1]].s);else up(t+s[f[x+1][l+1]].s);
}else{
if(f[y+1][l-2]!=f[y][l-2])up(t+s[f[y][l-2]].s);
if(f[y+2][l-1]!=f[y+2][l])up(t+s[f[y+2][l]].s);
}
}
if(y<n&&r<n&&!f[y+1][r+1]){
t=s[i].s+2+s[f[y+2][r+1]].s+s[f[y+1][r+2]].s;
if(x==y&&l==r){
if(f[y+1][r+2]!=f[y][r+2])up(t+s[f[y][r+2]].s+s[f[x-1][l+1]].s);else up(t+s[f[x-1][l+1]].s);
if(f[y+2][r+1]!=f[y+2][r])up(t+s[f[y+2][r]].s+s[f[x+1][l-1]].s);else up(t+s[f[x+1][l-1]].s);
}else{
if(f[y+1][r+2]!=f[y][r+2])up(t+s[f[y][r+2]].s);
if(f[y+2][r+1]!=f[y+2][r])up(t+s[f[y+2][r]].s);
}
}
}
return printf("%d",ans),0;
}

  

BZOJ4348 : [POI2016]Park wodny的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. hdu4607 Park Visit(树的直径)

    Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树

    C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...

  4. 转:php park、unpark、ord 函数使用方法(二进制流接口应用实例)

    在工作中,我也逐渐了解到park,unpark,ord对于二进制字节处理的强大. 下面我逐一介绍它们.     park,unpark,ord这3个函数,在我们工作中,用到它们的估计不多. 我在最近一 ...

  5. Kefa and Park

    #include<bits/stdc++.h> #define max 100005 using namespace std; int cats[max]; vector<int&g ...

  6. UVALive 4221 Walk in the Park 扫描线

    Walk in the Park 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemi ...

  7. B. Om Nom and Dark Park

    B. Om Nom and Dark Park 在满二叉树上的某些边上添加一些值.使得根节点到叶子节点的路径上的权值和都相等.求最少需要添加多少. 我们利用性质解题.   考察兄弟节点.由于他们从跟节 ...

  8. Codeforces Round #321 (Div. 2) C. Kefa and Park dfs

    C. Kefa and Park Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/probl ...

  9. LockSupport的park和unpark

    LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语. Java锁和同步器框架的核心AQS:AbstractQueuedSynchronizer,就是通过调用Lo ...

随机推荐

  1. error: library dfftpack has Fortran sources but no Fortran compiler found解决方法

    用pip install scipy 时提示 error: library dfftpack has Fortran sources but no Fortran compiler found 解决方 ...

  2. 什么是响应式Web设计?怎样进行?

    http://beforweb.com/node/6/page/0/3 开始第一篇.老规矩,先无聊的谈论天气一类的话题.十一长假,天气也终于开始有些秋天的味道,坐在屋里甚至觉得需要热咖啡.话说两年前也 ...

  3. powerdesigner奇淫技

    在日常开发中数据库的设计常常需要建立模型,而powerdesigner是个不错的选择.但很多时候用powerdesigner生成模型后再去创建表结构,会觉得烦和别扭.那么能不能数据库表建好后再生成模型 ...

  4. Hadoop入门程序WordCount的执行过程

    首先编写WordCount.java源文件,分别通过map和reduce方法统计文本中每个单词出现的次数,然后按照字母的顺序排列输出, Map过程首先是多个map并行提取多个句子里面的单词然后分别列出 ...

  5. Linux系统排查1——内存篇

    常见工作中,计算机系统的资源主要包括CPU,内存,硬盘以及网络,过度使用这些资源将使系统陷入困境.本系列一共四篇博文,结合我在实习期间的学习,介绍一些常见的Linux系统排障工具及方法. 第1篇——内 ...

  6. MFC RadioButton

    添加一组RadioButton 多个radio button,IDC_RADIO1,IDC_RADIO2,IDC_RADIO3 ..将IDC_RADIO1的Group属性选择上,其他不要选Group属 ...

  7. [Android Pro] fragment中嵌套viewpager,vierpager中有多个fragment,不显示

    referece to :  http://blog.csdn.net/mybook1122/article/details/24003343 现在好多应用流行一种布局.底部几个工具栏选项,上面也有类 ...

  8. Androidi性能优化之Java代码优化(摘自Android性能优化一书)

    代码优化不是应用开发的首要任务,提供良好的用户体验并专注于代码的可维护性,这才是你的首要任务.事实上,代码优化应该是最后才做,甚至完全可能不去做,不过,良好的优化可以使程序性能直接达到一个可接受的水平 ...

  9. 多源最短路(codevs 1077)

    题目描述 Description 已知n个点(n<=100),给你n*n的方阵,a[i,j]表示从第i个点到第j个点的直接距离. 现在有Q个询问,每个询问两个正整数,a和b,让你求a到b之间的最 ...

  10. 图像边缘检测——Sobel算子

    边缘是图像最基本的特征,其在计算机视觉.图像分析等应用中起着重要的作用,这是因为图像的边缘包含了用于识别的有用信息,是图像分析和模式识别的主要特征提取手段. 1.何为“图像边缘”? 在图像中,“边缘” ...