Hihocoder1673
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hihocoder1673相关的知识,希望对你有一定的参考价值。
这个题还是挺有意思的,得发现点性质,然后才能知道要怎么搞。
首先我们得知道这个合法段是连一起的,这个是一个很重要的一点,我们得知道如果10101010 可以,那么他的所有子段都是可以的。。。。。。。
这个应该是很好发现的? (那怎么才能发现这一点呢??????) 我们首先应该对单行分析,分析一下单行怎么搞,因为单行是矩阵的基础,然后考虑先填1010,这样搞,发现这个段的性质 这个手玩一下样例就可以了,很好发现的
(事实证明手玩样例是很重要的,很多题目都是手玩样例出来的)
这个的话我们可以通过手玩确定出来很好的性质,比如那道cf 的 d和这道
然后我们可以通过预处理知道当前这个点向上能衍生的最长长度的长度
然后根据上面的性质分成一个个的段,然后再这个段里面通过单调栈操作
下面是代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cmath> 6 #include <bitset> 7 #include <stack> 8 typedef long long ll; 9 using namespace std; 10 const int maxn=2100; 11 int n,m; 12 char s[maxn][maxn]; 13 int h[maxn][maxn]; 14 int li[maxn][maxn]; 15 int siz[maxn]; 16 stack<int> sta; 17 int main(){ 18 scanf("%d%d",&n,&m); 19 for(int i=1;i<=n;i++) scanf("%s",s[i]+1); 20 for(int i=1;i<=n;i++){ 21 for(int j=1;j<=m;j++){ 22 if(i==1) h[i][j]=1; 23 else{ 24 if(s[i][j]!=s[i-1][j]) h[i][j]=h[i-1][j]+1; 25 else h[i][j]=1; 26 } 27 } 28 } 29 30 int ans=0; 31 for(int i=1;i<=n;i++){ 32 int l,r; 33 for(int j=1;j<=m;j=r+1){ 34 l=j;r=j; 35 for(int k=j+1;k<=m;k++){ 36 if(s[i][k]!=s[i][k-1]) r=k; 37 } 38 for(int k=l;k<=r;k++) li[i][k]=h[i][k],siz[k]=1; 39 li[i][r+1]=0;li[i][l-1]=0; 40 while(!sta.empty()) sta.pop(); 41 sta.push(l-1); 42 for(int k=l;k<=r+1;k++){ 43 if(li[i][k]>=li[i][sta.top()]){ 44 sta.push(k); 45 }else{ 46 int len=0; 47 while(!sta.empty()&&li[i][k]<li[i][sta.top()]){ 48 len+=siz[sta.top()]; 49 ans=max(ans,len*li[i][sta.top()]); 50 sta.pop(); 51 } 52 sta.push(k);siz[k]+=len; 53 } 54 } 55 } 56 } 57 printf("%d ",ans); 58 return 0; 59 }
以上是关于Hihocoder1673的主要内容,如果未能解决你的问题,请参考以下文章
HihoCoder1673 : 01间隔矩阵([Offer收割]编程练习赛41)(单调队列)
poj1673 EXOCENTER OF A TRIANGLE