Fork me on GitHub

HDU4495-Rectangle

HDU4495-Rectangle

题意

给一个字符矩形(\(n\)*\(m\)),求其中最大的对称的等腰直角三角形的面积(包含的字符个数),其直角边分别平行于矩形的边(对称表示两边字符相等)

题解

总共可能有四种不同的矩形。可以先考虑直角在右下位置的等腰直角三角形,其余可以通过旋转矩形来得到。
\(dp[i][j]\)表示直角顶点在\((i,j)\)处的最大的三角形的直角边长度,可以得到递推式\(dp[i][j]=min(dp[i-1][j-1]+2,len)\),其中\(len\)表示从点\((i,j)\)分别向上,向左的两个字符串对称的最大长度。
\(len\)可以先预处理,点\((i,j)\)\(len\)\(mx[i][j]\)表示,每次二分就可以求出。

1、旋转矩形时记得\(swap(n,m)\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int base=131;
const ll mod=1e9+7;
const int N=510;
int t,n,m;
char s[N][N],tmp[N][N];
ll Hashr[N][N],Hashc[N][N];
ll sum[N];
int mx[N][N],dp[N][N];
int ans;


void getSum(){
	sum[0]=1;
	for(int i=1;i<=500;i++) sum[i]=(sum[i-1]*base)%mod;
}

void getHash(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			Hashr[i][j]=(Hashr[i][j-1]*base%mod+s[i][j])%mod;
		}
	}
	for(int j=1;j<=m;j++){
		for(int i=1;i<=n;i++){
			Hashc[i][j]=(Hashc[i-1][j]*base%mod+s[i][j])%mod;
		}
	}
}

bool check(int i,int j,int len){
	int r=j,l=r-len+1;
	ll nowr=(Hashr[i][r]-Hashr[i][l-1]*sum[len]%mod+mod)%mod;
	r=i;l=r-len+1;
	ll nowc=(Hashc[r][j]-Hashc[l-1][j]*sum[len]%mod+mod)%mod;
	if(nowr==nowc) return 1;
	return 0;
}

void init(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			int l=1,r=min(i,j);
			while(l<=r){
				int mid=(l+r)>>1;
				if(check(i,j,mid)){
					mx[i][j]=mid;
					l=mid+1;
				}else{
					r=mid-1;
				}
			}
		}
	}
}

void solve(){
	getHash();
	init();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			dp[i][j]=min(dp[i-1][j-1]+2,mx[i][j]);
			ans=max(ans,dp[i][j]);
		}
	}
}

//记得swap(n,m) 
void rotate(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			tmp[j][n-i+1]=s[i][j];
		}
	}
	swap(n,m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			s[i][j]=tmp[i][j];
		}
	}
}

int main(){
	scanf("%d",&t);
	getSum();
	while(t--){
		ans=0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
		solve();
		rotate();
		solve();
		rotate();
		solve();
		rotate();
		solve();
	
		if(ans%2) ans=(ans+1)/2*ans;
		else ans=ans/2*(ans+1);
		printf("%d\n",ans);
	}
	return 0;
}

posted @ 2020-03-15 16:18  qjy_73  阅读(151)  评论(0)    收藏  举报