考慮這是乙個0 1矩陣 我們對每一行進行 hash ,再對每一列進行 hash ,取兩個不同的 base ,這樣可以一定程度上保證 hash 的正確性,由於蒟蒻我比較菜,沒有寫雜湊表,只能 rp++rp++ 看有沒有重複了,橫行 d[i][j]=d[i][j-1]base1+a[i][j]d[i][j]=d[i][j−1]∗base1+a[i][j] ,再考慮豎列 sum[i][j]=sum[i-1][j]*base2+d[i][j]sum[i][j]=sum[i−1][j]∗base2+d[i][j] ,再將矩陣整個旋轉 180°,如果乙個子正方形旋轉前和旋轉後的 hash 值相同,則大概率下,這兩個矩陣相同。我們列舉方陣的邊長(注意不能二分,這玩意坑了我很久,我二分一直 wa ,仔細一想發現如果前面不滿足,後面滿足的情況也是存在的,不滿足單調性),列舉矩陣的點,進行 hash判斷,時間複雜度o(n³),下面貼**
//看了看ac記錄,貌似 rank1 ,比 rank2 快了差不多10倍?其實這題二進位制壓縮貌似也可做?不過工程量巨大?不管了, qaq
// 可能**略醜,借鑑思路即可。
#include#include#includeusing namespace std;
typedef unsigned long long ll;
ll base1=131,base2=233;
ll re()const ll n=305;
char s[n];ll a[n][n],d[n][n],sum[n][n],aa[n][n],sum2[n][n],n,m,qpow1[n],qpow2[n];
ll cal(ll x,ll y,ll l,ll type)
ll work(ll l)ll ans=0;
int main()
qpow1[0]=1;for(int i=1;i<=300;i++) qpow1[i]=qpow1[i-1]*base1;
qpow2[0]=1;for(int i=1;i<=300;i++) qpow2[i]=qpow2[i-1]*base2;
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
d[i][j]=d[i][j-1]*base1+a[i][j];
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
sum[i][j]=sum[i-1][j]*base2+d[i][j];
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
aa[i][j]=a[n-i+1][m-j+1];
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
d[i][j]=d[i][j-1]*base1+aa[i][j];
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
sum2[i][j]=sum2[i-1][j]*base2+d[i][j];
for(int i=1;i<=max(n,m);i++)
if(work(i)) ans=i;
if(ans!=1&&ans!=0)printf("%llu",ans);
else printf("-1\n");
}
二維hash矩陣(一)
鏈結 思路 把a b矩陣 雜湊為數字 存到set 怎樣hash 先把每行字首 hash 掉用函式可以 求出區間hash值 include using namespace std typedef unsigned long long ll const ll n 1010 ll m,n,a,b,q ll...
bzoj2462 二維hash 矩陣hash
二維hash 相當於每個位置有兩個權,行乙個,列乙個,然後推的方法和一維一樣 bzoj2462 include include include include include using namespace std define p1 131 define p2 1331 行和列的模數不能相同,否則...
洛谷P2742 二維凸包
有n個點,求凸包長度,0 n 10000 前置知識 向量的外積 叉積,用於判斷新加入的點能否與原本構成凸殼。a x1,y1 b x2,y 2 vec x1,y1 vec x2,y2 a x1,y1 b x 2,y2 a b x1y2 y1x 2 vec vec x1y2 y1x2 a b x1 y2...