洛谷2177(二維hash)

2022-07-24 07:51:09 字數 1638 閱讀 7957

考慮這是乙個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...