bzoj1567: [JSOI2008]Blue Mary的战役地图

xiaoxiao2021-02-28  132

传送门 二分答案+哈希。 二分边长,哈希判断是否相等。 注意,行/列上计算key时乘的数应不同。

#include<cstring> #include<cmath> #include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<map> #define ll long long using namespace std; ll a[2][55][55],f[2][55][55],t[55],b[2505]; int n,l,r,m,ans; inline ll read(){ ll x=0,f=1; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-48; return x*f; } inline ll cal(int x,int y,int z,int m){ ll val=1; for (int i=y;i<y+m;i++) val=val*3659+f[x][i][z+m-1]-f[x][i][z-1]*t[m]; return val; } inline int jud(int m){ int cnt=0; for (int i=1;i<=n-m+1;i++) for (int j=1;j<=n-m+1;j++) b[++cnt]=cal(0,i,j,m); sort(b+1,b+cnt+1); for (int i=1;i<=n-m+1;i++) for (int j=1;j<=n-m+1;j++){ ll t=cal(1,i,j,m); if (*lower_bound(b+1,b+cnt+1,t)==t) return 1; } return 0; } int main(){ n=read(); t[0]=1; for (int i=1;i<=n;i++) t[i]=t[i-1]*1789; for (int i=0;i<2;i++) for (int j=1;j<=n;j++) for (int k=1;k<=n;k++) a[i][j][k]=read(); for (int i=0;i<2;i++) for (int j=1;j<=n;j++){ f[i][j][0]=1; for (int k=1;k<=n;k++) f[i][j][k]=f[i][j][k-1]*1789+a[i][j][k]; } l=1,r=n; while (l<=r){ m=(l+r)/2; if (jud(m)) ans=m,l=m+1; else r=m-1; } printf("%d",ans); }
转载请注明原文地址: https://www.6miu.com/read-31184.html

最新回复(0)